readdwarf3.c revision 5d616dfbb8439dfd51a40ddf1dba970938baa1eb
15d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* -*- mode: C; c-basic-offset: 3; -*- */
2b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------------*/
4fba428cd266b8a39db641c5fd9523daa8939bed0tom/*--- Read DWARF3/4 ".debug_info" sections (DIE trees).            ---*/
5b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                 readdwarf3.c ---*/
6b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------------*/
7b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
8b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*
9b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   This file is part of Valgrind, a dynamic binary instrumentation
10b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   framework.
11b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1203f8d3fc25f5a45c5826259d1b33b7f310117279sewardj   Copyright (C) 2008-2012 OpenWorks LLP
13b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      info@open-works.co.uk
14b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
15b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   This program is free software; you can redistribute it and/or
16b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   modify it under the terms of the GNU General Public License as
17b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   published by the Free Software Foundation; either version 2 of the
18b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   License, or (at your option) any later version.
19b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
20b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   This program is distributed in the hope that it will be useful, but
21b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   WITHOUT ANY WARRANTY; without even the implied warranty of
22b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   General Public License for more details.
24b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
25b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   You should have received a copy of the GNU General Public License
26b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   along with this program; if not, write to the Free Software
27b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   02111-1307, USA.
29b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
30b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   The GNU General Public License is contained in the file COPYING.
31b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
32b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Neither the names of the U.S. Department of Energy nor the
33b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   University of California nor the names of its contributors may be
34b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   used to endorse or promote products derived from this software
35b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   without prior written permission.
36b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/
37b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
388b68b64759254d514d98328c496cbd88cde4c9a5njn#if defined(VGO_linux) || defined(VGO_darwin)
398b68b64759254d514d98328c496cbd88cde4c9a5njn
40b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* REFERENCE (without which this code will not make much sense):
41b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
42b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   DWARF Debugging Information Format, Version 3,
43b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   dated 20 December 2005 (the "D3 spec").
44b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
45b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Available at http://www.dwarfstd.org/Dwarf3.pdf.  There's also a
46b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   .doc (MS Word) version, but for some reason the section numbers
47b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   between the Word and PDF versions differ by 1 in the first digit.
48b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   All section references in this code are to the PDF version.
49b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
50b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   CURRENT HACKS:
51b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
52b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   DW_TAG_{const,volatile}_type no DW_AT_type is allowed; it is
53b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      assumed to mean "const void" or "volatile void" respectively.
54b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GDB appears to interpret them like this, anyway.
55b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
56b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   In many cases it is important to know the svma of a CU (the "base
57b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   address of the CU", as the D3 spec calls it).  There are some
58b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   situations in which the spec implies this value is unknown, but the
59b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Dwarf3 produced by gcc-4.1 seems to assume is not unknown but
60b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   merely zero when not explicitly stated.  So we too have to make
61b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   that assumption.
62b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   POTENTIAL BUG?  Spotted 6 Sept 08.  Why doesn't
649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   unitary_range_list() bias the resulting range list in the same way
659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   that its more general cousin, get_range_list(), does?  I don't
669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   know.
679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
68b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TODO, 2008 Feb 17:
69b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
70b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   get rid of cu_svma_known and document the assumed-zero svma hack.
71b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
72b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ML_(sizeOfType): differentiate between zero sized types and types
73b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for which the size is unknown.  Is this important?  I don't know.
74b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
75a2af13d238de6b212f1d69e7b316538f37a7abbasewardj   DW_TAG_array_types: deal with explicit sizes (currently we compute
76b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   the size from the bounds and the element size, although that's
77b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   fragile, if the bounds incompletely specified, or completely
78b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   absent)
79b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
80b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Document reason for difference (by 1) of stack preening depth in
81b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parse_var_DIE vs parse_type_DIE.
82b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
83b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Don't hand to ML_(addVars), vars whose locations are entirely in
84b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   registers (DW_OP_reg*).  This is merely a space-saving
85b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   optimisation, as ML_(evaluate_Dwarf3_Expr) should handle these
86b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   expressions correctly, by failing to evaluate them and hence
87b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   effectively ignoring the variable with which they are associated.
88b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
89a2af13d238de6b212f1d69e7b316538f37a7abbasewardj   Deal with DW_TAG_array_types which have element size != stride
90b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
91b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   In some cases, the info for a variable is split between two
92b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   different DIEs (generally a declarer and a definer).  We punt on
93b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   these.  Could do better here.
94b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
95b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   The 'data_bias' argument passed to the expression evaluator
96b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   (ML_(evaluate_Dwarf3_Expr)) should really be changed to a
97b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   MaybeUWord, to make it clear when we do vs don't know what it is
98b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for the evaluation of an expression.  At the moment zero is passed
99b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for this parameter in the don't know case.  That's a bit fragile
100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   and obscure; using a MaybeUWord would be clearer.
101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   POTENTIAL PERFORMANCE IMPROVEMENTS:
103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Currently, duplicate removal and all other queries for the type
1059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   entities array is done using cuOffset-based pointing, which
1069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   involves a binary search (VG_(lookupXA)) for each access.  This is
1079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   wildly inefficient, although simple.  It would be better to
1089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   translate all the cuOffset-based references (iow, all the "R" and
1099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   "Rs" fields in the TyEnts in 'tyents') to direct index numbers in
1109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   'tyents' right at the start of dedup_types(), and use direct
1119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   indexing (VG_(indexXA)) wherever possible after that.
1129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
1139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   cmp__XArrays_of_AddrRange is also a performance bottleneck.  Move
1149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(indexXA) into pub_tool_xarray.h so it can be inlined at all use
1159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   points, and possibly also make an _UNCHECKED version which skips
1169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   the range checks in performance-critical situations such as this.
117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Handle interaction between read_DIE and parse_{var,type}_DIE
119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   better.  Currently read_DIE reads the entire DIE just to find where
120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   the end is (and for debug printing), so that it can later reliably
121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   move the cursor to the end regardless of what parse_{var,type}_DIE
122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   do.  This means many DIEs (most, even?) are read twice.  It would
123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   be smarter to make parse_{var,type}_DIE return a Bool indicating
124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   whether or not they advanced the DIE cursor, and only if they
125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   didn't should read_DIE itself read through the DIE.
126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ML_(addVar) and add_var_to_arange: quite a lot of DiAddrRanges have
128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   zero variables in their .vars XArray.  Rather than have an XArray
129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   with zero elements (which uses 2 malloc'd blocks), allow the .vars
130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   pointer to be NULL in this case.
131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   More generally, reduce the amount of memory allocated and freed
133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while reading Dwarf3 type/variable information.  Even modest (20MB)
134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   objects cause this module to allocate and free hundreds of
135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   thousands of small blocks, and ML_(arena_malloc) and its various
136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   groupies always show up at the top of performance profiles. */
137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_basics.h"
139588658b13b5ad77672f323d48fe9da0ca60b0bcbtom#include "pub_core_debuginfo.h"
140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_libcbase.h"
141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_libcassert.h"
142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_libcprint.h"
1436c591e15c1d6402a2a755310f005f795b68e7e38sewardj#include "pub_core_libcsetjmp.h"   // setjmp facilities
144d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj#include "pub_core_hashtable.h"
145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_options.h"
146f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_tooliface.h"    /* VG_(needs) */
147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_xarray.h"
1489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj#include "pub_core_wordfm.h"
149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_misc.h"             /* dinfo_zalloc/free */
1505d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj#include "priv_image.h"
151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_tytypes.h"
152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_d3basics.h"
153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_storage.h"
154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_readdwarf3.h"       /* self */
155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Basic machinery for parsing DIEs.                    ---*/
160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define TRACE_D3(format, args...) \
164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (td3) { VG_(printf)(format, ## args); }
165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj#define D3_INVALID_CUOFF  ((UWord)(-1UL))
1679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj#define D3_FAKEVOID_CUOFF ((UWord)(-2UL))
168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct {
1715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice sli;      // to which this cursor applies
1725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiOffT  sli_next; // offset in underlying DiImage; must be >= sli.ioff
1736bd9dc18c043927c1196caba20a327238a179c42florian      void (*barf)( const HChar* ) __attribute__((noreturn));
1746bd9dc18c043927c1196caba20a327238a179c42florian      const HChar* barfstr;
175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Cursor;
177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic inline Bool is_sane_Cursor ( Cursor* c ) {
179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (!c)                return False;
180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (!c->barf)          return False;
181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (!c->barfstr)       return False;
1825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (!ML_(sli_is_valid)(c->sli))    return False;
1835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (c->sli.ioff == DiOffT_INVALID) return False;
1845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (c->sli_next < c->sli.ioff)     return False;
185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return True;
186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj// Initialise a cursor from a DiSlice (ELF section, really) so as to
1895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj// start reading at offset |sli_initial_offset| from the start of the
1905d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj// slice.
1915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic void init_Cursor ( /*OUT*/Cursor* c,
1925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                          DiSlice sli,
1935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                          ULong   sli_initial_offset,
1945d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                          __attribute__((noreturn)) void (*barf)(const HChar*),
1956bd9dc18c043927c1196caba20a327238a179c42florian                          const HChar* barfstr )
196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(c);
1985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   VG_(bzero_inline)(c, sizeof(*c));
1995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli              = sli;
2005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next         = c->sli.ioff + sli_initial_offset;
201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   c->barf             = barf;
202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   c->barfstr          = barfstr;
203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool is_at_end_Cursor ( Cursor* c ) {
207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
2085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return c->sli_next >= c->sli.ioff + c->sli.szB;
209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline ULong get_position_of_Cursor ( Cursor* c ) {
212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
2135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return c->sli_next - c->sli.ioff;
214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline void set_position_of_Cursor ( Cursor* c, ULong pos ) {
2165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next = c->sli.ioff + pos;
217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic /*signed*/Long get_remaining_length_Cursor ( Cursor* c ) {
221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
2225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return c->sli.ioff + c->sli.szB - c->sli_next;
223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2255d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj//static void* get_address_of_Cursor ( Cursor* c ) {
2265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj//   vg_assert(is_sane_Cursor(c));
2275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj//   return &c->region_start_img[ c->region_next ];
2285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj//}
2295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
2305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic DiCursor get_DiCursor_from_Cursor ( Cursor* c ) {
2315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return mk_DiCursor(c->sli.img, c->sli_next);
232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* FIXME: document assumptions on endianness for
235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   get_UShort/UInt/ULong. */
236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic inline UChar get_UChar ( Cursor* c ) {
237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar r;
2385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   vg_assert(is_sane_Cursor(c));
2395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (c->sli_next + sizeof(UChar) > c->sli.ioff + c->sli.szB) {
240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c->barf(c->barfstr);
241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*NOTREACHED*/
242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(0);
243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   r = ML_(img_get_UChar)(c->sli.img, c->sli_next);
2455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next += sizeof(UChar);
246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return r;
247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic UShort get_UShort ( Cursor* c ) {
249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UShort r;
250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
2515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (c->sli_next + sizeof(UShort) > c->sli.ioff + c->sli.szB) {
252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c->barf(c->barfstr);
253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*NOTREACHED*/
254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(0);
255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   r = ML_(img_get_UShort)(c->sli.img, c->sli_next);
2575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next += sizeof(UShort);
258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return r;
259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic UInt get_UInt ( Cursor* c ) {
261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt r;
262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
2635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (c->sli_next + sizeof(UInt) > c->sli.ioff + c->sli.szB) {
264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c->barf(c->barfstr);
265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*NOTREACHED*/
266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(0);
267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   r = ML_(img_get_UInt)(c->sli.img, c->sli_next);
2695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next += sizeof(UInt);
270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return r;
271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic ULong get_ULong ( Cursor* c ) {
273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ULong r;
274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
2755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (c->sli_next + sizeof(ULong) > c->sli.ioff + c->sli.szB) {
276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c->barf(c->barfstr);
277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*NOTREACHED*/
278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(0);
279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   r = ML_(img_get_ULong)(c->sli.img, c->sli_next);
2815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next += sizeof(ULong);
282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return r;
283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic ULong get_ULEB128 ( Cursor* c ) {
285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ULong result;
286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int   shift;
287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar byte;
288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* unroll first iteration */
289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   byte = get_UChar( c );
290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   result = (ULong)(byte & 0x7f);
291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (LIKELY(!(byte & 0x80))) return result;
292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   shift = 7;
293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* end unroll first iteration */
294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   do {
295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      byte = get_UChar( c );
296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      result |= ((ULong)(byte & 0x7f)) << shift;
297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      shift += 7;
298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } while (byte & 0x80);
299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return result;
300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Long get_SLEB128 ( Cursor* c ) {
302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ULong  result = 0;
303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int    shift = 0;
304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar  byte;
305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   do {
306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      byte = get_UChar(c);
307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      result |= ((ULong)(byte & 0x7f)) << shift;
308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      shift += 7;
309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } while (byte & 0x80);
310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (shift < 64 && (byte & 0x40))
311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      result |= -(1ULL << shift);
312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return result;
313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Assume 'c' points to the start of a string.  Return a DiCursor of
3165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   whatever it points at, and advance it past the terminating zero.
3175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   This makes it safe for the caller to then copy the string with
3185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   ML_(addStr), since (w.r.t. image overruns) the process of advancing
3195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   past the terminating zero will already have "vetted" the string. */
3205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic DiCursor get_AsciiZ ( Cursor* c ) {
3215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UChar uc;
3225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiCursor res = get_DiCursor_from_Cursor(c);
323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   do { uc = get_UChar(c); } while (uc != 0);
324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return res;
325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic ULong peek_ULEB128 ( Cursor* c ) {
3285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiOffT here = c->sli_next;
3295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   ULong  r    = get_ULEB128( c );
3305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next = here;
331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return r;
332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic UChar peek_UChar ( Cursor* c ) {
3345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiOffT here = c->sli_next;
3355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UChar  r    = get_UChar( c );
3365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next = here;
337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return r;
338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic ULong get_Dwarfish_UWord ( Cursor* c, Bool is_dw64 ) {
341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return is_dw64 ? get_ULong(c) : (ULong) get_UInt(c);
342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic UWord get_UWord ( Cursor* c ) {
345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(sizeof(UWord) == sizeof(void*));
346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (sizeof(UWord) == 4) return get_UInt(c);
347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (sizeof(UWord) == 8) return get_ULong(c);
348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(0);
349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Read a DWARF3 'Initial Length' field */
352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic ULong get_Initial_Length ( /*OUT*/Bool* is64,
353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                  Cursor* c,
3546bd9dc18c043927c1196caba20a327238a179c42florian                                  const HChar* barfMsg )
355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ULong w64;
357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt  w32;
358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   *is64 = False;
359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   w32 = get_UInt( c );
360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (w32 >= 0xFFFFFFF0 && w32 < 0xFFFFFFFF) {
361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c->barf( barfMsg );
362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   else if (w32 == 0xFFFFFFFF) {
364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      *is64 = True;
365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      w64   = get_ULong( c );
366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } else {
367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      *is64 = False;
368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      w64 = (ULong)w32;
369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return w64;
371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- "CUConst" structure                                  ---*/
377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define N_ABBV_CACHE 32
381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Holds information that is constant through the parsing of a
383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Compilation Unit.  This is basically plumbed through to
384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   everywhere. */
385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct {
387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Call here if anything goes wrong */
3886bd9dc18c043927c1196caba20a327238a179c42florian      void (*barf)( const HChar* ) __attribute__((noreturn));
389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Is this 64-bit DWARF ? */
390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   is_dw64;
391fba428cd266b8a39db641c5fd9523daa8939bed0tom      /* Which DWARF version ?  (2, 3 or 4) */
392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UShort version;
393055b0f85aaa42477a803d445885c389561d3d3c8sewardj      /* Length of this Compilation Unit, as stated in the
394055b0f85aaa42477a803d445885c389561d3d3c8sewardj         .unit_length :: InitialLength field of the CU Header.
395055b0f85aaa42477a803d445885c389561d3d3c8sewardj         However, this size (as specified by the D3 spec) does not
396055b0f85aaa42477a803d445885c389561d3d3c8sewardj         include the size of the .unit_length field itself, which is
397055b0f85aaa42477a803d445885c389561d3d3c8sewardj         either 4 or 12 bytes (32-bit or 64-bit Dwarf3).  That value
398055b0f85aaa42477a803d445885c389561d3d3c8sewardj         can be obtained through the expression ".is_dw64 ? 12 : 4". */
399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ULong  unit_length;
400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Offset of start of this unit in .debug_info */
401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord  cu_start_offset;
402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* SVMA for this CU.  In the D3 spec, is known as the "base
403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         address of the compilation unit (last para sec 3.1.1).
404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Needed for (amongst things) interpretation of location-list
405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         values. */
406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr   cu_svma;
407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   cu_svma_known;
4085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* The debug_abbreviations table to be used for this Unit */
4105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      //UChar* debug_abbv;
411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Upper bound on size thereof (an overestimate, in general) */
4125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      //UWord  debug_abbv_maxszB;
4135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      /* A bounded area of the image, to be used as the
4145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         debug_abbreviations table tobe used for this Unit. */
4155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice debug_abbv;
4165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
4175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      /* Image information for various sections. */
4185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_str;
4195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_ranges;
4205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_loc;
4215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_line;
4225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_info;
4235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_types;
4245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_info_alt;
4255d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_str_alt;
426f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      /* How much to add to .debug_types resp. alternate .debug_info offsets
427f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         in cook_die*.  */
428f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      UWord  types_cuOff_bias;
429f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      UWord  alt_cuOff_bias;
430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* --- Needed so we can add stuff to the string table. --- */
431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      struct _DebugInfo* di;
432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* --- a cache for set_abbv_Cursor --- */
433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* abbv_code == (ULong)-1 for an unused entry. */
434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      struct { ULong abbv_code; UWord posn; } saC_cache[N_ABBV_CACHE];
435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord saC_cache_queries;
436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord saC_cache_misses;
437d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
438d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      /* True if this came from .debug_types; otherwise it came from
439d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         .debug_info.  */
440d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      Bool is_type_unit;
441d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      /* For a unit coming from .debug_types, these hold the TU's type
442d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         signature and the uncooked DIE offset of the TU's signatured
443d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         type.  For a unit coming from .debug_info, these are unused.  */
444d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      ULong type_signature;
445d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      ULong type_offset;
446d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
447d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      /* Signatured type hash; computed once and then shared by all
448d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         CUs.  */
449d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      VgHashTable signature_types;
450f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj
451f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      /* True if this came from alternate .debug_info; otherwise
452f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         it came from normal .debug_info or .debug_types.  */
453f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      Bool is_alt_info;
454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   CUConst;
456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
458d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj/* Return the cooked value of DIE depending on whether CC represents a
459f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   .debug_types unit.  To cook a DIE, we pretend that the .debug_info,
460f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   .debug_types and optional alternate .debug_info sections form
461f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   a contiguous whole, so that DIEs coming from .debug_types are numbered
462f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   starting at the end of .debug_info and DIEs coming from alternate
463f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   .debug_info are numbered starting at the end of .debug_types.  */
464d935068fc7b53c8a826b3436cdfccd5b7d446903sewardjstatic UWord cook_die( CUConst* cc, UWord die )
465d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj{
466d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   if (cc->is_type_unit)
467f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      die += cc->types_cuOff_bias;
468f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   else if (cc->is_alt_info)
469f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      die += cc->alt_cuOff_bias;
470d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   return die;
471d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj}
472d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
473d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj/* Like cook_die, but understand that DIEs coming from a
474f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   DW_FORM_ref_sig8 reference are already cooked.  Also, handle
475f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   DW_FORM_GNU_ref_alt from within primary .debug_info or .debug_types
476f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   as reference to alternate .debug_info.  */
477d935068fc7b53c8a826b3436cdfccd5b7d446903sewardjstatic UWord cook_die_using_form( CUConst *cc, UWord die, DW_FORM form)
478d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj{
479d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   if (form == DW_FORM_ref_sig8)
480d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      return die;
481f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   if (form == DW_FORM_GNU_ref_alt)
482f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      return die + cc->alt_cuOff_bias;
483d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   return cook_die( cc, die );
484d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj}
485d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
486f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj/* Return the uncooked offset of DIE and set *TYPE_FLAG to true if the DIE
487f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   came from the .debug_types section and *ALT_FLAG to true if the DIE
488f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   came from alternate .debug_info section.  */
489f7c9714ea0cde18daaecb896278e85e780d3bd75sewardjstatic UWord uncook_die( CUConst *cc, UWord die, /*OUT*/Bool *type_flag,
490f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                         Bool *alt_flag )
491d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj{
492f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   *alt_flag = False;
493f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   *type_flag = False;
4945d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   /* The use of escn_debug_{info,types}.szB seems safe to me even if
4955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      escn_debug_{info,types} are DiSlice_INVALID (meaning the
4965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      sections were not found), because DiSlice_INVALID.szB is always
4975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      zero.  That said, it seems unlikely we'd ever get here if
4985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      .debug_info or .debug_types were missing. */
4995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (die >= cc->escn_debug_info.szB) {
5005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      if (die >= cc->escn_debug_info.szB + cc->escn_debug_types.szB) {
501f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         *alt_flag = True;
5025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         die -= cc->escn_debug_info.szB + cc->escn_debug_types.szB;
503f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      } else {
504f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         *type_flag = True;
5055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         die -= cc->escn_debug_info.szB;
506f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      }
507d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   }
508d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   return die;
509d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj}
510d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
513b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Helper functions for Guarded Expressions             ---*/
514b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
515b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
516b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
517b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Parse the location list starting at img-offset 'debug_loc_offset'
518b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   in .debug_loc.  Results are biased with 'svma_of_referencing_CU'
519b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   and so I believe are correct SVMAs for the object as a whole.  This
520b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   function allocates the UChar*, and the caller must deallocate it.
521b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   The resulting block is in so-called Guarded-Expression format.
522b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Guarded-Expression format is similar but not identical to the DWARF3
524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   location-list format.  The format of each returned block is:
525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
526b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar biasMe;
527b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar isEnd;
528b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      followed by zero or more of
529b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
530b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      (Addr aMin;  Addr aMax;  UShort nbytes;  ..bytes..;  UChar isEnd)
531b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   '..bytes..' is an standard DWARF3 location expression which is
533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   valid when aMin <= pc <= aMax (possibly after suitable biasing).
534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   The number of bytes in '..bytes..' is nbytes.
536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   The end of the sequence is marked by an isEnd == 1 value.  All
538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   previous isEnd values must be zero.
539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   biasMe is 1 if the aMin/aMax fields need this DebugInfo's
541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   text_bias added before use, and 0 if the GX is this is not
542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   necessary (is ready to go).
543b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Hence the block can be quickly parsed and is self-describing.  Note
545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   that aMax is 1 less than the corresponding value in a DWARF3
546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   location list.  Zero length ranges, with aMax == aMin-1, are not
547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   allowed.
548b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/
5499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* 2008-sept-12: moved ML_(pp_GX) from here to d3basics.c, where
5509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   it more logically belongs. */
5519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
553402c9eed11b9b60c6e134d05db938e395466cf99tom/* Apply a text bias to a GX. */
554402c9eed11b9b60c6e134d05db938e395466cf99tomstatic void bias_GX ( /*MOD*/GExpr* gx, struct _DebugInfo* di )
555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UShort nbytes;
557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar* p = &gx->payload[0];
55886781fabbfc019b752f9605e487cfce77b2a592atom   UChar* pA;
559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar  uc;
560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   uc = *p++; /*biasMe*/
561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (uc == 0)
562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return;
563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(uc == 1);
564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   p[-1] = 0; /* mark it as done */
565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      uc = *p++;
567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (uc == 1)
568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break; /*isEnd*/
569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(uc == 0);
57068a2ebd9384661a85a4674fe8310c595ad494305sewardj      /* t-bias aMin */
57186781fabbfc019b752f9605e487cfce77b2a592atom      pA = (UChar*)p;
57286781fabbfc019b752f9605e487cfce77b2a592atom      ML_(write_Addr)(pA, ML_(read_Addr)(pA) + di->text_debug_bias);
57368a2ebd9384661a85a4674fe8310c595ad494305sewardj      p += sizeof(Addr);
57468a2ebd9384661a85a4674fe8310c595ad494305sewardj      /* t-bias aMax */
57586781fabbfc019b752f9605e487cfce77b2a592atom      pA = (UChar*)p;
57686781fabbfc019b752f9605e487cfce77b2a592atom      ML_(write_Addr)(pA, ML_(read_Addr)(pA) + di->text_debug_bias);
57768a2ebd9384661a85a4674fe8310c595ad494305sewardj      p += sizeof(Addr);
57868a2ebd9384661a85a4674fe8310c595ad494305sewardj      /* nbytes, and actual expression */
57986781fabbfc019b752f9605e487cfce77b2a592atom      nbytes = ML_(read_UShort)(p); p += sizeof(UShort);
580b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      p += nbytes;
581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
582b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
584b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
5855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic GExpr* make_singleton_GX ( DiCursor block, ULong nbytes )
586b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
587b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   SizeT  bytesReqd;
588b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   GExpr* gx;
589b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar *p, *pstart;
590b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
591b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(sizeof(UWord) == sizeof(Addr));
592b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(nbytes <= 0xFFFF); /* else we overflow the nbytes field */
593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bytesReqd
594b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      =   sizeof(UChar)  /*biasMe*/    + sizeof(UChar) /*!isEnd*/
595b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        + sizeof(UWord)  /*aMin*/      + sizeof(UWord) /*aMax*/
5965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj        + sizeof(UShort) /*nbytes*/    + (SizeT)nbytes
597b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        + sizeof(UChar); /*isEnd*/
598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   gx = ML_(dinfo_zalloc)( "di.readdwarf3.msGX.1",
6009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                           sizeof(GExpr) + bytesReqd );
601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(gx);
602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   p = pstart = &gx->payload[0];
604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
60586781fabbfc019b752f9605e487cfce77b2a592atom   p = ML_(write_UChar)(p, 0);        /*biasMe*/
60686781fabbfc019b752f9605e487cfce77b2a592atom   p = ML_(write_UChar)(p, 0);        /*!isEnd*/
60786781fabbfc019b752f9605e487cfce77b2a592atom   p = ML_(write_Addr)(p, 0);         /*aMin*/
60886781fabbfc019b752f9605e487cfce77b2a592atom   p = ML_(write_Addr)(p, ~0);        /*aMax*/
60986781fabbfc019b752f9605e487cfce77b2a592atom   p = ML_(write_UShort)(p, nbytes);  /*nbytes*/
6105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   ML_(cur_read_get)(p, block, nbytes); p += nbytes;
61186781fabbfc019b752f9605e487cfce77b2a592atom   p = ML_(write_UChar)(p, 1);        /*isEnd*/
612b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert( (SizeT)(p - pstart) == bytesReqd);
614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert( &gx->payload[bytesReqd]
615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              == ((UChar*)gx) + sizeof(GExpr) + bytesReqd );
616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
617b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return gx;
618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
619b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic GExpr* make_general_GX ( CUConst* cc,
622b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                Bool     td3,
6235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                ULong    debug_loc_offset,
624b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                Addr     svma_of_referencing_CU )
625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Addr      base;
627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Cursor    loc;
628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   XArray*   xa; /* XArray of UChar */
629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   GExpr*    gx;
630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Word      nbytes;
631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(sizeof(UWord) == sizeof(Addr));
6335d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (!ML_(sli_is_valid)(cc->escn_debug_loc) || cc->escn_debug_loc.szB == 0)
634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("make_general_GX: .debug_loc is empty/missing");
635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   init_Cursor( &loc, cc->escn_debug_loc, 0, cc->barf,
637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                "Overrun whilst reading .debug_loc section(2)" );
638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   set_position_of_Cursor( &loc, debug_loc_offset );
639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   TRACE_D3("make_general_GX (.debug_loc_offset = %llu, ioff = %llu) {\n",
6415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            debug_loc_offset, (ULong)get_DiCursor_from_Cursor(&loc).ioff );
642b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Who frees this xa?  It is freed before this fn exits. */
6449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.mgGX.1",
6459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                    ML_(dinfo_free),
646b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    sizeof(UChar) );
647b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
648b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   { UChar c = 1; /*biasMe*/ VG_(addBytesToXA)( xa, &c, sizeof(c) ); }
649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   base = 0;
651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool  acquire;
653b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord len;
654b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Read a (host-)word pair.  This is something of a hack since
655b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         the word size to read is really dictated by the ELF file;
656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         however, we assume we're reading a file with the same
657b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         word-sizeness as the host.  Reasonably enough. */
658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord w1 = get_UWord( &loc );
659b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord w2 = get_UWord( &loc );
660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("   %08lx %08lx\n", w1, w2);
662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 == 0 && w2 == 0)
663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break; /* end of list */
664b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 == -1UL) {
666b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* new value for 'base' */
667b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         base = w2;
668b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         continue;
669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
670b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* else a location expression follows */
672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* else enumerate [w1+base, w2+base) */
673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* w2 is 1 past end of range, as per D3 defn for "DW_AT_high_pc"
674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (sec 2.17.2) */
675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 > w2) {
676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("negative range is for .debug_loc expr at "
6775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  "file offset %llu\n",
678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  debug_loc_offset);
679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         cc->barf( "negative range in .debug_loc section" );
680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* ignore zero length ranges */
683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      acquire = w1 < w2;
684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      len     = (UWord)get_UShort( &loc );
685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (acquire) {
687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UWord  w;
688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UShort s;
689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UChar  c;
690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         c = 0; /* !isEnd*/
691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(addBytesToXA)( xa, &c, sizeof(c) );
692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         w = w1    + base + svma_of_referencing_CU;
693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(addBytesToXA)( xa, &w, sizeof(w) );
694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         w = w2 -1 + base + svma_of_referencing_CU;
695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(addBytesToXA)( xa, &w, sizeof(w) );
696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s = (UShort)len;
697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(addBytesToXA)( xa, &s, sizeof(s) );
698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
699b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (len > 0) {
701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UChar byte = get_UChar( &loc );
702b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("%02x", (UInt)byte);
703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (acquire)
704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            VG_(addBytesToXA)( xa, &byte, 1 );
705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         len--;
706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("\n");
708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   { UChar c = 1; /*isEnd*/ VG_(addBytesToXA)( xa, &c, sizeof(c) ); }
711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   nbytes = VG_(sizeXA)( xa );
713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(nbytes >= 1);
714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
7159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   gx = ML_(dinfo_zalloc)( "di.readdwarf3.mgGX.2", sizeof(GExpr) + nbytes );
716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(gx);
717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(memcpy)( &gx->payload[0], (UChar*)VG_(indexXA)(xa,0), nbytes );
718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert( &gx->payload[nbytes]
719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              == ((UChar*)gx) + sizeof(GExpr) + nbytes );
720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(deleteXA)( xa );
722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3("}\n");
724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return gx;
726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
727b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Helper functions for range lists and CU headers      ---*/
732b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Denotes an address range.  Both aMin and aMax are included in the
736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   range; hence a complete range is (0, ~0) and an empty range is any
737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   (X, X-1) for X > 0.*/
738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct { Addr aMin; Addr aMax; }
740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   AddrRange;
741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
742b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
7439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Generate an arbitrary structural total ordering on
7449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   XArray* of AddrRange. */
7459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic Word cmp__XArrays_of_AddrRange ( XArray* rngs1, XArray* rngs2 )
7469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
7479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Word n1, n2, i;
7489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   tl_assert(rngs1 && rngs2);
7499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   n1 = VG_(sizeXA)( rngs1 );
7509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   n2 = VG_(sizeXA)( rngs2 );
7519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (n1 < n2) return -1;
7529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (n1 > n2) return 1;
7539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   for (i = 0; i < n1; i++) {
7549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      AddrRange* rng1 = (AddrRange*)VG_(indexXA)( rngs1, i );
7559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      AddrRange* rng2 = (AddrRange*)VG_(indexXA)( rngs2, i );
7569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (rng1->aMin < rng2->aMin) return -1;
7579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (rng1->aMin > rng2->aMin) return 1;
7589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (rng1->aMax < rng2->aMax) return -1;
7599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (rng1->aMax > rng2->aMax) return 1;
7609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
7619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   return 0;
7629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj}
7639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
7649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
765b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic XArray* /* of AddrRange */ empty_range_list ( void )
767b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   XArray* xa; /* XArray of AddrRange */
769b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Who frees this xa?  varstack_preen() does. */
7709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.erl.1",
7719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                    ML_(dinfo_free),
772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    sizeof(AddrRange) );
773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return xa;
774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
7779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj__attribute__((noinline))
778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic XArray* unitary_range_list ( Addr aMin, Addr aMax )
779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   XArray*   xa;
781b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   AddrRange pair;
782b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(aMin <= aMax);
783b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Who frees this xa?  varstack_preen() does. */
7849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   xa = VG_(newXA)( ML_(dinfo_zalloc),  "di.readdwarf3.url.1",
7859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                    ML_(dinfo_free),
786b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    sizeof(AddrRange) );
787b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   pair.aMin = aMin;
788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   pair.aMax = aMax;
789b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(addToXA)( xa, &pair );
790b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return xa;
791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
793b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
794b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Enumerate the address ranges starting at img-offset
795b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   'debug_ranges_offset' in .debug_ranges.  Results are biased with
796b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   'svma_of_referencing_CU' and so I believe are correct SVMAs for the
797b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   object as a whole.  This function allocates the XArray, and the
798b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   caller must deallocate it. */
799b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
800b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic XArray* /* of AddrRange */
801b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       get_range_list ( CUConst* cc,
802b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        Bool     td3,
803b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        UWord    debug_ranges_offset,
804b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        Addr     svma_of_referencing_CU )
805b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
806b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Addr      base;
807b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Cursor    ranges;
808b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   XArray*   xa; /* XArray of AddrRange */
809b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   AddrRange pair;
810b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
8115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (!ML_(sli_is_valid)(cc->escn_debug_ranges)
8125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj       || cc->escn_debug_ranges.szB == 0)
813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("get_range_list: .debug_ranges is empty/missing");
814b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
8155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   init_Cursor( &ranges, cc->escn_debug_ranges, 0, cc->barf,
816b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                "Overrun whilst reading .debug_ranges section(2)" );
817b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   set_position_of_Cursor( &ranges, debug_ranges_offset );
818b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
819b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Who frees this xa?  varstack_preen() does. */
8209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.grl.1", ML_(dinfo_free),
821b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    sizeof(AddrRange) );
822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   base = 0;
823b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
824b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Read a (host-)word pair.  This is something of a hack since
825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         the word size to read is really dictated by the ELF file;
826b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         however, we assume we're reading a file with the same
827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         word-sizeness as the host.  Reasonably enough. */
828b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord w1 = get_UWord( &ranges );
829b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord w2 = get_UWord( &ranges );
830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 == 0 && w2 == 0)
832b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break; /* end of list. */
833b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 == -1UL) {
835b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* new value for 'base' */
836b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         base = w2;
837b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         continue;
838b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* else enumerate [w1+base, w2+base) */
841b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* w2 is 1 past end of range, as per D3 defn for "DW_AT_high_pc"
842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (sec 2.17.2) */
843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 > w2)
844b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         cc->barf( "negative range in .debug_ranges section" );
845b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 < w2) {
846b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         pair.aMin = w1     + base + svma_of_referencing_CU;
847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         pair.aMax = w2 - 1 + base + svma_of_referencing_CU;
848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vg_assert(pair.aMin <= pair.aMax);
849b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(addToXA)( xa, &pair );
850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
851b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return xa;
853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Parse the Compilation Unit header indicated at 'c' and
857b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   initialise 'cc' accordingly. */
858b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic __attribute__((noinline))
859b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid parse_CU_Header ( /*OUT*/CUConst* cc,
860b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                       Bool td3,
861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                       Cursor* c,
8625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                       DiSlice escn_debug_abbv,
863f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj		       Bool type_unit,
864f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                       Bool alt_info )
865b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
866b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar  address_size;
8675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   ULong  debug_abbrev_offset;
868b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int    i;
869b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
870b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(memset)(cc, 0, sizeof(*cc));
871b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(c && c->barf);
872b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   cc->barf = c->barf;
873b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
874b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* initial_length field */
875b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   cc->unit_length
876b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      = get_Initial_Length( &cc->is_dw64, c,
877b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           "parse_CU_Header: invalid initial-length field" );
878b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
879b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3("   Length:        %lld\n", cc->unit_length );
880b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
881b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* version */
882b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   cc->version = get_UShort( c );
883fba428cd266b8a39db641c5fd9523daa8939bed0tom   if (cc->version != 2 && cc->version != 3 && cc->version != 4)
884fba428cd266b8a39db641c5fd9523daa8939bed0tom      cc->barf( "parse_CU_Header: is neither DWARF2 nor DWARF3 nor DWARF4" );
885b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3("   Version:       %d\n", (Int)cc->version );
886b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
887b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* debug_abbrev_offset */
888b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   debug_abbrev_offset = get_Dwarfish_UWord( c, cc->is_dw64 );
8895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (debug_abbrev_offset >= escn_debug_abbv.szB)
890b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf( "parse_CU_Header: invalid debug_abbrev_offset" );
8915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   TRACE_D3("   Abbrev Offset: %lld\n", debug_abbrev_offset );
892b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
893b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* address size.  If this isn't equal to the host word size, just
894b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      give up.  This makes it safe to assume elsewhere that
89531452303b095a76295b08096b2840276db808b81sewardj      DW_FORM_addr and DW_FORM_ref_addr can be treated as a host
89631452303b095a76295b08096b2840276db808b81sewardj      word. */
897b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   address_size = get_UChar( c );
898b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (address_size != sizeof(void*))
899b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf( "parse_CU_Header: invalid address_size" );
900b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3("   Pointer Size:  %d\n", (Int)address_size );
901b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
902d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   cc->is_type_unit = type_unit;
903f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   cc->is_alt_info = alt_info;
904d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
905d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   if (type_unit) {
906d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      cc->type_signature = get_ULong( c );
907d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      cc->type_offset = get_Dwarfish_UWord( c, cc->is_dw64 );
908d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   }
909d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
9105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   /* Set up cc->debug_abbv to point to the relevant table for this
9115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      CU.  Set its .szB so that at least we can't read off the end of
9125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      the debug_abbrev section -- potentially (and quite likely) too
9135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      big, if this isn't the last table in the section, but at least
9145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      it's safe.
9155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
9165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      This amounts to taking debug_abbv_escn and moving the start
9175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      position along by debug_abbrev_offset bytes, hence forming a
9185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      smaller DiSlice which has the same end point.  Since we checked
9195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      just above that debug_abbrev_offset is less than the size of
9205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      debug_abbv_escn, this should leave us with a nonempty slice. */
9215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   vg_assert(debug_abbrev_offset < escn_debug_abbv.szB);
9225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   cc->debug_abbv      = escn_debug_abbv;
9235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   cc->debug_abbv.ioff += debug_abbrev_offset;
9245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   cc->debug_abbv.szB  -= debug_abbrev_offset;
9255d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
926b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* and empty out the set_abbv_Cursor cache */
927b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (0) VG_(printf)("XXXXXX initialise set_abbv_Cursor cache\n");
928b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < N_ABBV_CACHE; i++) {
929b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->saC_cache[i].abbv_code = (ULong)-1; /* unused */
930b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->saC_cache[i].posn = 0;
931b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
932b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   cc->saC_cache_queries = 0;
933b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   cc->saC_cache_misses = 0;
934b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
935b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
936b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
937b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Set up 'c' so it is ready to parse the abbv table entry code
938b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   'abbv_code' for this compilation unit.  */
939b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic __attribute__((noinline))
940b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid set_abbv_Cursor ( /*OUT*/Cursor* c, Bool td3,
941b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                       CUConst* cc, ULong abbv_code )
942b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
943b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int   i;
944b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ULong acode;
945b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
946b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (abbv_code == 0)
947b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("set_abbv_Cursor: abbv_code == 0" );
948b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
949b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* (ULong)-1 is used to represent an empty cache slot.  So we can't
950b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      allow it.  In any case no valid DWARF3 should make a reference
951b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      to a negative abbreviation code.  [at least, they always seem to
952b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      be numbered upwards from zero as far as I have seen] */
953b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(abbv_code != (ULong)-1);
954b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
955b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* First search the cache. */
956b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (0) VG_(printf)("XXXXXX search set_abbv_Cursor cache\n");
957b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   cc->saC_cache_queries++;
958b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i < N_ABBV_CACHE; i++) {
959b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* No need to test the cached abbv_codes for -1 (empty), since
960b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         we just asserted that abbv_code is not -1. */
9615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      if (LIKELY(cc->saC_cache[i].abbv_code == abbv_code)) {
9625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         /* Found it.  Set up the parser using the cached position,
9635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            and move this cache entry to the front. */
9645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (0) VG_(printf)("XXXXXX found in set_abbv_Cursor cache\n");
9655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         init_Cursor( c, cc->debug_abbv, cc->saC_cache[i].posn,
9665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                      cc->barf,
9675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                      "Overrun whilst parsing .debug_abbrev section(1)" );
9685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (i > 0) {
9695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ULong t_abbv_code = cc->saC_cache[i].abbv_code;
9705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            UWord t_posn      = cc->saC_cache[i].posn;
9715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            while (i > 0) {
9725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               cc->saC_cache[i] = cc->saC_cache[i-1];
9735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               i--;
9745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            }
9755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            cc->saC_cache[0].abbv_code = t_abbv_code;
9765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            cc->saC_cache[0].posn      = t_posn;
9775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
9785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         return;
9795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      }
980b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
981b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
982b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* No.  It's not in the cache.  We have to search through
983b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      .debug_abbrev, of course taking care to update the cache
984b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      when done. */
985b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
986b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   cc->saC_cache_misses++;
9875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   init_Cursor( c, cc->debug_abbv, 0, cc->barf,
988b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               "Overrun whilst parsing .debug_abbrev section(2)" );
989b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
990b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Now iterate though the table until we find the requested
991b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      entry. */
992b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
9934c245e595b9f6300d3120408ca873f7115d9cc7dnjn      //ULong atag;
9944c245e595b9f6300d3120408ca873f7115d9cc7dnjn      //UInt  has_children;
995b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      acode = get_ULEB128( c );
996b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (acode == 0) break; /* end of the table */
997b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (acode == abbv_code) break; /* found it */
9984c245e595b9f6300d3120408ca873f7115d9cc7dnjn      /*atag         = */ get_ULEB128( c );
9994c245e595b9f6300d3120408ca873f7115d9cc7dnjn      /*has_children = */ get_UChar( c );
1000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      //TRACE_D3("   %llu      %s    [%s]\n",
1001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      //         acode, pp_DW_TAG(atag), pp_DW_children(has_children));
1002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
1003b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ULong at_name = get_ULEB128( c );
1004b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ULong at_form = get_ULEB128( c );
1005b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (at_name == 0 && at_form == 0) break;
1006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         //TRACE_D3("    %18s %s\n",
1007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         //         pp_DW_AT(at_name), pp_DW_FORM(at_form));
1008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1009b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1011b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (acode == 0) {
1012b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Not found.  This is fatal. */
1013b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("set_abbv_Cursor: abbv_code not found");
1014b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1015b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1016b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Otherwise, 'c' is now set correctly to parse the relevant entry,
1017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      starting from the abbreviation entry's tag.  So just cache
1018b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      the result, and return. */
1019b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = N_ABBV_CACHE-1; i > N_ABBV_CACHE/2; i--) {
1020b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->saC_cache[i] = cc->saC_cache[i-1];
1021b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1022b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (0) VG_(printf)("XXXXXX update set_abbv_Cursor cache\n");
1023b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   cc->saC_cache[N_ABBV_CACHE/2].abbv_code = abbv_code;
1024b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   cc->saC_cache[N_ABBV_CACHE/2].posn = get_position_of_Cursor(c);
1025b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1026b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1027d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj/* This represents a single signatured type.  It maps a type signature
1028d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   (a ULong) to a cooked DIE offset.  Objects of this type are stored
1029d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   in the type signature hash table.  */
1030d935068fc7b53c8a826b3436cdfccd5b7d446903sewardjtypedef
1031d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   struct D3SignatureType {
1032d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      struct D3SignatureType *next;
1033d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      UWord data;
1034d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      ULong type_signature;
1035d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      UWord die;
1036d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   }
1037d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   D3SignatureType;
1038d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
1039d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj/* Record a signatured type in the hash table.  */
1040d935068fc7b53c8a826b3436cdfccd5b7d446903sewardjstatic void record_signatured_type ( VgHashTable tab,
1041d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                                     ULong type_signature,
1042d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                                     UWord die )
1043d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj{
1044d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   D3SignatureType *dstype = ML_(dinfo_zalloc) ( "di.readdwarf3.sigtype",
1045d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                                                 sizeof(D3SignatureType) );
1046d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   dstype->data = (UWord) type_signature;
1047d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   dstype->type_signature = type_signature;
1048d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   dstype->die = die;
1049d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   VG_(HT_add_node) ( tab, dstype );
1050d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj}
1051d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
1052d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj/* Given a type signature hash table and a type signature, return the
1053d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   cooked DIE offset of the type.  If the type cannot be found, call
1054d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   BARF.  */
1055d935068fc7b53c8a826b3436cdfccd5b7d446903sewardjstatic UWord lookup_signatured_type ( VgHashTable tab,
1056d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                                      ULong type_signature,
10576bd9dc18c043927c1196caba20a327238a179c42florian                                      void (*barf)( const HChar* ) __attribute__((noreturn)) )
1058d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj{
1059d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   D3SignatureType *dstype = VG_(HT_lookup) ( tab, (UWord) type_signature );
1060d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   /* This may be unwarranted chumminess with the hash table
1061d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      implementation.  */
1062d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   while ( dstype != NULL && dstype->type_signature != type_signature)
1063d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      dstype = dstype->next;
1064d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   if (dstype == NULL) {
1065d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      barf("lookup_signatured_type: could not find signatured type");
1066d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      /*NOTREACHED*/
1067d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      vg_assert(0);
1068d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   }
1069d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   return dstype->die;
1070d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj}
1071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
10735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Represents Form data.  If szB is 1/2/4/8 then the result is in the
10745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   lowest 1/2/4/8 bytes of u.val.  If szB is zero or negative then the
10755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   result is an image section beginning at u.cur and with size -szB.
10765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   No other szB values are allowed. */
10775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjtypedef
10785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   struct {
10795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      Long szB; // 1, 2, 4, 8 or non-positive values only.
10805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      union { ULong val; DiCursor cur; } u;
10815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   }
10825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   FormContents;
1083b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
10845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* From 'c', get the Form data into 'cts'.  Either it gets a 1/2/4/8
10855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   byte scalar value, or (a reference to) zero or more bytes starting
10865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   at a DiCursor.*/
1087b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
10885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjvoid get_Form_contents ( /*OUT*/FormContents* cts,
1089b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                         CUConst* cc, Cursor* c,
1090b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                         Bool td3, DW_FORM form )
1091b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
10925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   VG_(bzero_inline)(cts, sizeof(*cts));
1093b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   switch (form) {
1094b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_data1:
10955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)(UChar)get_UChar(c);
10965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 1;
10975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%u", (UInt)cts->u.val);
1098b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_data2:
11005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)(UShort)get_UShort(c);
11015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 2;
11025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%u", (UInt)cts->u.val);
1103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1104b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_data4:
11055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)(UInt)get_UInt(c);
11065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 4;
11075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%u", (UInt)cts->u.val);
1108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
11090b5bf911d9d40b8dd3130f6043ef7ba68a9f446esewardj      case DW_FORM_data8:
11105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = get_ULong(c);
11115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 8;
11125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%llu", cts->u.val);
11130b5bf911d9d40b8dd3130f6043ef7ba68a9f446esewardj         break;
1114fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_sec_offset:
11155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)get_Dwarfish_UWord( c, cc->is_dw64 );
11165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = cc->is_dw64 ? 8 : 4;
11175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%llu", cts->u.val);
1118fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_sdata:
11205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)(Long)get_SLEB128(c);
11215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 8;
11225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%lld", (Long)cts->u.val);
1123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1124fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_udata:
11255d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)(Long)get_ULEB128(c);
11265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 8;
11275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%llu", (Long)cts->u.val);
1128fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_addr:
1130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* note, this is a hack.  DW_FORM_addr is defined as getting
1131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            a word the size of the target machine as defined by the
1132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            address_size field in the CU Header.  However,
1133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            parse_CU_Header() rejects all inputs except those for
1134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            which address_size == sizeof(Word), hence we can just
1135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            treat it as a (host) Word.  */
11365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)(UWord)get_UWord(c);
11375d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
11385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("0x%lx", (UWord)cts->u.val);
1139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
114031452303b095a76295b08096b2840276db808b81sewardj
114131452303b095a76295b08096b2840276db808b81sewardj      case DW_FORM_ref_addr:
114231452303b095a76295b08096b2840276db808b81sewardj         /* We make the same word-size assumption as DW_FORM_addr. */
114331452303b095a76295b08096b2840276db808b81sewardj         /* What does this really mean?  From D3 Sec 7.5.4,
114431452303b095a76295b08096b2840276db808b81sewardj            description of "reference", it would appear to reference
114531452303b095a76295b08096b2840276db808b81sewardj            some other DIE, by specifying the offset from the
114631452303b095a76295b08096b2840276db808b81sewardj            beginning of a .debug_info section.  The D3 spec mentions
114731452303b095a76295b08096b2840276db808b81sewardj            that this might be in some other shared object and
114831452303b095a76295b08096b2840276db808b81sewardj            executable.  But I don't see how the name of the other
114931452303b095a76295b08096b2840276db808b81sewardj            object/exe is specified.
115031452303b095a76295b08096b2840276db808b81sewardj
115131452303b095a76295b08096b2840276db808b81sewardj            At least for the DW_FORM_ref_addrs created by icc11, the
115231452303b095a76295b08096b2840276db808b81sewardj            references seem to be within the same object/executable.
115331452303b095a76295b08096b2840276db808b81sewardj            So for the moment we merely range-check, to see that they
115431452303b095a76295b08096b2840276db808b81sewardj            actually do specify a plausible offset within this
115531452303b095a76295b08096b2840276db808b81sewardj            object's .debug_info, and return the value unchanged.
1156ee93cdbee1e6a0db21be1ec4533a4022c9566388sewardj
1157ee93cdbee1e6a0db21be1ec4533a4022c9566388sewardj            In DWARF 2, DW_FORM_ref_addr is address-sized, but in
1158ee93cdbee1e6a0db21be1ec4533a4022c9566388sewardj            DWARF 3 and later, it is offset-sized.
115931452303b095a76295b08096b2840276db808b81sewardj         */
1160ee93cdbee1e6a0db21be1ec4533a4022c9566388sewardj         if (cc->version == 2) {
11615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            cts->u.val = (ULong)(UWord)get_UWord(c);
11625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            cts->szB   = sizeof(UWord);
1163ee93cdbee1e6a0db21be1ec4533a4022c9566388sewardj         } else {
11645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            cts->u.val = get_Dwarfish_UWord(c, cc->is_dw64);
11655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            cts->szB   = cc->is_dw64 ? sizeof(ULong) : sizeof(UInt);
1166ee93cdbee1e6a0db21be1ec4533a4022c9566388sewardj         }
11675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("0x%lx", (UWord)cts->u.val);
11685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (0) VG_(printf)("DW_FORM_ref_addr 0x%lx\n", (UWord)cts->u.val);
11695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (/* the following is surely impossible, but ... */
11705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             !ML_(sli_is_valid)(cc->escn_debug_info)
11715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             || cts->u.val >= (ULong)cc->escn_debug_info.szB) {
117231452303b095a76295b08096b2840276db808b81sewardj            /* Hmm.  Offset is nonsensical for this object's .debug_info
117331452303b095a76295b08096b2840276db808b81sewardj               section.  Be safe and reject it. */
117431452303b095a76295b08096b2840276db808b81sewardj            cc->barf("get_Form_contents: DW_FORM_ref_addr points "
117531452303b095a76295b08096b2840276db808b81sewardj                     "outside .debug_info");
117631452303b095a76295b08096b2840276db808b81sewardj         }
117731452303b095a76295b08096b2840276db808b81sewardj         break;
117831452303b095a76295b08096b2840276db808b81sewardj
1179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_strp: {
1180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* this is an offset into .debug_str */
1181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UWord uw = (UWord)get_Dwarfish_UWord( c, cc->is_dw64 );
11825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (!ML_(sli_is_valid)(cc->escn_debug_str)
11835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             || uw >= cc->escn_debug_str.szB)
118431452303b095a76295b08096b2840276db808b81sewardj            cc->barf("get_Form_contents: DW_FORM_strp "
1185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     "points outside .debug_str");
1186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* FIXME: check the entire string lies inside debug_str,
1187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            not just the first byte of it. */
11885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor str
11895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            = ML_(cur_plus)( ML_(cur_from_sli)(cc->escn_debug_str), uw );
11905d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (td3) {
11915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            HChar* tmp = ML_(cur_read_strdup)(str, "di.getFC.1");
11925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            TRACE_D3("(indirect string, offset: 0x%lx): %s", uw, tmp);
11935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ML_(dinfo_free)(tmp);
11945d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
11955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = str;
11965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)(1 + (ULong)ML_(cur_strlen)(str));
1197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_string: {
12005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor str = get_AsciiZ(c);
12015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (td3) {
12025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            HChar* tmp = ML_(cur_read_strdup)(str, "di.getFC.2");
12035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            TRACE_D3("%s", tmp);
12045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ML_(dinfo_free)(tmp);
12055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
12065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = str;
1207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* strlen is safe because get_AsciiZ already 'vetted' the
1208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            entire string */
12095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)(1 + (ULong)ML_(cur_strlen)(str));
1210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1212fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_ref1: {
12135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UChar u8   = get_UChar(c);
12145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UWord res  = cc->cu_start_offset + (UWord)u8;
12155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)res;
12165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
1217fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("<%lx>", res);
1218fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1219fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1220fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_ref2: {
12215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UShort u16 = get_UShort(c);
12225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UWord  res = cc->cu_start_offset + (UWord)u16;
12235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)res;
12245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
1225fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("<%lx>", res);
1226fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1227fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_ref4: {
12295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UInt  u32  = get_UInt(c);
12305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UWord res  = cc->cu_start_offset + (UWord)u32;
12315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)res;
12325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
1233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("<%lx>", res);
1234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1236fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_ref8: {
12375d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong u64  = get_ULong(c);
12385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UWord res  = cc->cu_start_offset + (UWord)u64;
12395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)res;
12405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
1241fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("<%lx>", res);
1242fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1243fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1244fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_ref_udata: {
12455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong u64  = get_ULEB128(c);
12465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UWord res  = cc->cu_start_offset + (UWord)u64;
12475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)res;
12485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
1249fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("<%lx>", res);
1250fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1251fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_flag: {
1253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UChar u8 = get_UChar(c);
1254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("%u", (UInt)u8);
12555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)u8;
12565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 1;
1257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1259fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_flag_present:
1260fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("1");
12615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = 1;
12625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 1;
1263fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_block1: {
12655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64b;
12665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64   = (ULong)get_UChar(c);
12675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor block = get_DiCursor_from_Cursor(c);
1268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("%llu byte block: ", u64);
1269b2250d38b573099db3bde67e8f1bbeb789542076sewardj         for (u64b = u64; u64b > 0; u64b--) {
1270b2250d38b573099db3bde67e8f1bbeb789542076sewardj            UChar u8 = get_UChar(c);
1271b2250d38b573099db3bde67e8f1bbeb789542076sewardj            TRACE_D3("%x ", (UInt)u8);
1272b2250d38b573099db3bde67e8f1bbeb789542076sewardj         }
12735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = block;
12745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)u64;
1275b2250d38b573099db3bde67e8f1bbeb789542076sewardj         break;
1276b2250d38b573099db3bde67e8f1bbeb789542076sewardj      }
1277b2250d38b573099db3bde67e8f1bbeb789542076sewardj      case DW_FORM_block2: {
12785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64b;
12795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64   = (ULong)get_UShort(c);
12805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor block = get_DiCursor_from_Cursor(c);
1281b2250d38b573099db3bde67e8f1bbeb789542076sewardj         TRACE_D3("%llu byte block: ", u64);
1282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (u64b = u64; u64b > 0; u64b--) {
1283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            UChar u8 = get_UChar(c);
1284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            TRACE_D3("%x ", (UInt)u8);
1285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
12865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = block;
12875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)u64;
1288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1290fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_block4: {
12915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64b;
12925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64   = (ULong)get_UInt(c);
12935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor block = get_DiCursor_from_Cursor(c);
1294fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("%llu byte block: ", u64);
1295fba428cd266b8a39db641c5fd9523daa8939bed0tom         for (u64b = u64; u64b > 0; u64b--) {
1296fba428cd266b8a39db641c5fd9523daa8939bed0tom            UChar u8 = get_UChar(c);
1297fba428cd266b8a39db641c5fd9523daa8939bed0tom            TRACE_D3("%x ", (UInt)u8);
1298fba428cd266b8a39db641c5fd9523daa8939bed0tom         }
12995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = block;
13005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)u64;
1301fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1302fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1303fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_exprloc:
1304fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_block: {
13055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64b;
13065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64   = (ULong)get_ULEB128(c);
13075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor block = get_DiCursor_from_Cursor(c);
1308fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("%llu byte block: ", u64);
1309fba428cd266b8a39db641c5fd9523daa8939bed0tom         for (u64b = u64; u64b > 0; u64b--) {
1310fba428cd266b8a39db641c5fd9523daa8939bed0tom            UChar u8 = get_UChar(c);
1311fba428cd266b8a39db641c5fd9523daa8939bed0tom            TRACE_D3("%x ", (UInt)u8);
1312fba428cd266b8a39db641c5fd9523daa8939bed0tom         }
13135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = block;
13145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)u64;
1315fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1316fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1317fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_ref_sig8: {
1318fba428cd266b8a39db641c5fd9523daa8939bed0tom         ULong  u64b;
1319d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         ULong  signature = get_ULong (c);
1320d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         ULong  work = signature;
1321fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("8 byte signature: ");
1322fba428cd266b8a39db641c5fd9523daa8939bed0tom         for (u64b = 8; u64b > 0; u64b--) {
1323d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            UChar u8 = work & 0xff;
1324fba428cd266b8a39db641c5fd9523daa8939bed0tom            TRACE_D3("%x ", (UInt)u8);
1325d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            work >>= 8;
1326fba428cd266b8a39db641c5fd9523daa8939bed0tom         }
1327d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* Due to the way that the hash table is constructed, the
1328d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            resulting DIE offset here is already "cooked".  See
1329d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            cook_die_using_form.  */
13305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = lookup_signatured_type (cc->signature_types, signature,
13315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                              c->barf);
13325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
1333fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1334fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1335fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_indirect:
13365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents (cts, cc, c, td3, (DW_FORM)get_ULEB128(c));
1337fba428cd266b8a39db641c5fd9523daa8939bed0tom         return;
1338fba428cd266b8a39db641c5fd9523daa8939bed0tom
1339f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      case DW_FORM_GNU_ref_alt:
13405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = get_Dwarfish_UWord(c, cc->is_dw64);
13415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = cc->is_dw64 ? sizeof(ULong) : sizeof(UInt);
13425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("0x%lx", (UWord)cts->u.val);
13435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (0) VG_(printf)("DW_FORM_GNU_ref_alt 0x%lx\n", (UWord)cts->u.val);
13445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (/* the following is surely impossible, but ... */
13455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             !ML_(sli_is_valid)(cc->escn_debug_info_alt)
13465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             || cts->u.val >= (ULong)cc->escn_debug_info_alt.szB) {
1347f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            /* Hmm.  Offset is nonsensical for this object's .debug_info
1348f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj               section.  Be safe and reject it. */
1349f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            cc->barf("get_Form_contents: DW_FORM_ref_addr points "
1350f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                     "outside alternate .debug_info");
1351f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         }
1352f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         break;
1353f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj
1354f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      case DW_FORM_GNU_strp_alt: {
1355f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         /* this is an offset into alternate .debug_str */
13565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         SizeT uw = (UWord)get_Dwarfish_UWord( c, cc->is_dw64 );
13575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (!ML_(sli_is_valid)(cc->escn_debug_str_alt)
13585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             || uw >= cc->escn_debug_str_alt.szB)
1359f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            cc->barf("get_Form_contents: DW_FORM_GNU_strp_alt "
1360f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                     "points outside alternate .debug_str");
1361f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         /* FIXME: check the entire string lies inside debug_str,
1362f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            not just the first byte of it. */
13635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor str
13645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            = ML_(cur_plus)( ML_(cur_from_sli)(cc->escn_debug_str_alt), uw);
13655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (td3) {
13665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            HChar* tmp = ML_(cur_read_strdup)(str, "di.getFC.3");
13675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            TRACE_D3("(indirect alt string, offset: 0x%lx): %s", uw, tmp);
13685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ML_(dinfo_free)(tmp);
13695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
13705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = str;
13715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)(1 + (ULong)ML_(cur_strlen)(str));
1372f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         break;
1373f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      }
1374f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj
1375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      default:
137631452303b095a76295b08096b2840276db808b81sewardj         VG_(printf)(
13775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            "get_Form_contents: unhandled %d (%s) at <%llx>\n",
137831452303b095a76295b08096b2840276db808b81sewardj            form, ML_(pp_DW_FORM)(form), get_position_of_Cursor(c));
1379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         c->barf("get_Form_contents: unhandled DW_FORM");
1380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
1385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
1386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Parsing of variable-related DIEs                     ---*/
1387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
1388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
1389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
1391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct _TempVar {
13921636d33c13958b9c0e7d3059cdd5005746418eb2florian      HChar*  name; /* in DebugInfo's .strchunks */
1393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Represent ranges economically.  nRanges is the number of
1394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ranges.  Cases:
1395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         0: .rngOneMin .rngOneMax .manyRanges are all zero
1396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         1: .rngOneMin .rngOneMax hold the range; .rngMany is NULL
1397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         2: .rngOneMin .rngOneMax are zero; .rngMany holds the ranges.
1398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         This is merely an optimisation to avoid having to allocate
1399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         and free the XArray in the common (98%) of cases where there
1400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         is zero or one address ranges. */
1401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord   nRanges;
1402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr    rngOneMin;
1403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr    rngOneMax;
14049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      XArray* rngMany; /* of AddrRange.  NON-UNIQUE PTR in AR_DINFO. */
14059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* Do not free .rngMany, since many TempVars will have the same
14069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         value.  Instead the associated storage is to be freed by
14079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         deleting 'rangetree', which stores a single copy of each
14089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         range. */
1409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* --- */
1410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int     level;
14119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      UWord   typeR; /* a cuOff */
1412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GExpr*  gexpr; /* for this variable */
1413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GExpr*  fbGX;  /* to find the frame base of the enclosing fn, if
1414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        any */
14151636d33c13958b9c0e7d3059cdd5005746418eb2florian      HChar*  fName; /* declaring file name, or NULL */
1416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int     fLine; /* declaring file line number, or zero */
1417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* offset in .debug_info, so that abstract instances can be
1418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         found to satisfy references from concrete instances. */
1419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord   dioff;
1420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord   absOri; /* so the absOri fields refer to dioff fields
1421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                         in some other, related TempVar. */
1422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TempVar;
1424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
14257cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define N_D3_VAR_STACK 48
1426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
1428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct {
1429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Contains the range stack: a stack of address ranges, one
1430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         stack entry for each nested scope.
1431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Some scope entries are created by function definitions
1433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (DW_AT_subprogram), and for those, we also note the GExpr
1434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         derived from its DW_AT_frame_base attribute, if any.
1435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Consequently it should be possible to find, for any
1436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         variable's DIE, the GExpr for the the containing function's
1437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT_frame_base by scanning back through the stack to find
1438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         the nearest entry associated with a function.  This somewhat
1439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         elaborate scheme is provided so as to make it possible to
1440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         obtain the correct DW_AT_frame_base expression even in the
1441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         presence of nested functions (or to be more precise, in the
1442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         presence of nested DW_AT_subprogram DIEs).
1443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      */
1444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int     sp; /* [sp] is innermost active entry; sp==-1 for empty
1445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     stack */
1446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      XArray* ranges[N_D3_VAR_STACK]; /* XArray of AddrRange */
1447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int     level[N_D3_VAR_STACK];  /* D3 DIE levels */
1448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool    isFunc[N_D3_VAR_STACK]; /* from DW_AT_subprogram? */
1449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GExpr*  fbGX[N_D3_VAR_STACK];   /* if isFunc, contains the FB
1450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                         expr, else NULL */
1451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* The file name table.  Is a mapping from integer index to the
14525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         (permanent) copy of the string in in DebugInfo's .strchunks. */
1453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      XArray* /* of UChar* */ filenameTable;
1454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   D3VarParser;
1456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
14576bd9dc18c043927c1196caba20a327238a179c42florianstatic void varstack_show ( D3VarParser* parser, const HChar* str ) {
1458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Word i, j;
1459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(printf)("  varstack (%s) {\n", str);
1460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i <= parser->sp; i++) {
1461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      XArray* xa = parser->ranges[i];
1462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(xa);
1463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(printf)("    [%ld] (level %d)", i, parser->level[i]);
1464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (parser->isFunc[i]) {
1465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(printf)(" (fbGX=%p)", parser->fbGX[i]);
1466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else {
1467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vg_assert(parser->fbGX[i] == NULL);
1468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(printf)(": ");
1470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (VG_(sizeXA)( xa ) == 0) {
1471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(printf)("** empty PC range array **");
1472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else {
1473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (j = 0; j < VG_(sizeXA)( xa ); j++) {
1474b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            AddrRange* range = (AddrRange*) VG_(indexXA)( xa, j );
1475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            vg_assert(range);
1476a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart            VG_(printf)("[%#lx,%#lx] ", range->aMin, range->aMax);
1477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(printf)("\n");
1480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(printf)("  }\n");
1482b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Remove from the stack, all entries with .level > 'level' */
1485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
1486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid varstack_preen ( D3VarParser* parser, Bool td3, Int level )
1487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool changed = False;
1489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp < N_D3_VAR_STACK);
1490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
1491b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(parser->sp >= -1);
1492b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (parser->sp == -1) break;
1493b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (parser->level[parser->sp] <= level) break;
1494b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (0)
1495b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("BBBBAAAA varstack_pop [newsp=%d]\n", parser->sp-1);
1496b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(parser->ranges[parser->sp]);
1497b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Who allocated this xa?  get_range_list() or
1498b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         unitary_range_list(). */
1499b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(deleteXA)( parser->ranges[parser->sp] );
1500b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parser->ranges[parser->sp] = NULL;
1501b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parser->level[parser->sp]  = 0;
1502b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parser->isFunc[parser->sp] = False;
1503b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parser->fbGX[parser->sp]   = NULL;
1504b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parser->sp--;
1505b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      changed = True;
1506b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1507b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (changed && td3)
1508b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      varstack_show( parser, "after preen" );
1509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void varstack_push ( CUConst* cc,
1512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                            D3VarParser* parser,
1513b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                            Bool td3,
1514b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                            XArray* ranges, Int level,
1515b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                            Bool    isFunc, GExpr* fbGX ) {
1516b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (0)
1517b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3("BBBBAAAA varstack_push[newsp=%d]: %d  %p\n",
1518b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            parser->sp+1, level, ranges);
1519b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1520b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* First we need to zap everything >= 'level', as we are about to
1521b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      replace any previous entry at 'level', so .. */
1522b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   varstack_preen(parser, /*td3*/False, level-1);
1523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp >= -1);
1525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp < N_D3_VAR_STACK);
1526b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (parser->sp == N_D3_VAR_STACK-1)
1527b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("varstack_push: N_D3_VAR_STACK is too low; "
1528b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               "increase and recompile");
1529b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (parser->sp >= 0)
1530b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(parser->level[parser->sp] < level);
1531b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->sp++;
1532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->ranges[parser->sp] == NULL);
1533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->level[parser->sp]  == 0);
1534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->isFunc[parser->sp] == False);
1535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->fbGX[parser->sp]   == NULL);
1536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(ranges != NULL);
1537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (!isFunc) vg_assert(fbGX == NULL);
1538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->ranges[parser->sp] = ranges;
1539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->level[parser->sp]  = level;
1540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->isFunc[parser->sp] = isFunc;
1541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->fbGX[parser->sp]   = fbGX;
1542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (td3)
1543b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      varstack_show( parser, "after push" );
1544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
15475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* cts is derived from a DW_AT_location and so refers either to a
15485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   location expression or to a location list.  Figure out which, and
15495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   in both cases bundle the expression or location list into a
15505d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   so-called GExpr (guarded expression). */
1551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
15525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic GExpr* get_GX ( CUConst* cc, Bool td3, const FormContents* cts )
1553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   GExpr* gexpr = NULL;
15555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (cts->szB < 0) {
15565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      /* represents a non-empty in-line location expression, and
15575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur points at the image bytes */
15585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      gexpr = make_singleton_GX( cts->u.cur, (ULong)(- cts->szB) );
1559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   else
15615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (cts->szB > 0) {
15625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      /* represents a location list.  cts->u.val is the offset of it
15635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         in .debug_loc. */
1564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (!cc->cu_svma_known)
1565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         cc->barf("get_GX: location list, but CU svma is unknown");
15665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      gexpr = make_general_GX( cc, td3, cts->u.val, cc->cu_svma );
1567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   else {
1569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(0); /* else caller is bogus */
1570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return gexpr;
1572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1573b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1574b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
1576b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid read_filename_table( /*MOD*/D3VarParser* parser,
15775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                          CUConst* cc, ULong debug_line_offset,
1578b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                          Bool td3 )
1579b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1580b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool   is_dw64;
1581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Cursor c;
1582b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Word   i;
1583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UShort version;
1584b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar  opcode_base;
15851636d33c13958b9c0e7d3059cdd5005746418eb2florian   HChar* str;
1586b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1587b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser && cc && cc->barf);
15885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (!ML_(sli_is_valid)(cc->escn_debug_line)
15895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj       || cc->escn_debug_line.szB <= debug_line_offset) {
1590b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("read_filename_table: .debug_line is missing?");
15915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   }
1592b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
15935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   init_Cursor( &c, cc->escn_debug_line, debug_line_offset, cc->barf,
1594b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                "Overrun whilst reading .debug_line section(1)" );
1595b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
15964c245e595b9f6300d3120408ca873f7115d9cc7dnjn   /* unit_length = */
15974c245e595b9f6300d3120408ca873f7115d9cc7dnjn      get_Initial_Length( &is_dw64, &c,
1598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           "read_filename_table: invalid initial-length field" );
1599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   version = get_UShort( &c );
1600fba428cd266b8a39db641c5fd9523daa8939bed0tom   if (version != 2 && version != 3 && version != 4)
1601fba428cd266b8a39db641c5fd9523daa8939bed0tom     cc->barf("read_filename_table: Only DWARF version 2, 3 and 4 line info "
1602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              "is currently supported.");
16034c245e595b9f6300d3120408ca873f7115d9cc7dnjn   /*header_length              = (ULong)*/ get_Dwarfish_UWord( &c, is_dw64 );
16044c245e595b9f6300d3120408ca873f7115d9cc7dnjn   /*minimum_instruction_length = */ get_UChar( &c );
1605fba428cd266b8a39db641c5fd9523daa8939bed0tom   if (version >= 4)
1606fba428cd266b8a39db641c5fd9523daa8939bed0tom      /*maximum_operations_per_insn = */ get_UChar( &c );
16074c245e595b9f6300d3120408ca873f7115d9cc7dnjn   /*default_is_stmt            = */ get_UChar( &c );
16084c245e595b9f6300d3120408ca873f7115d9cc7dnjn   /*line_base                  = (Char)*/ get_UChar( &c );
16094c245e595b9f6300d3120408ca873f7115d9cc7dnjn   /*line_range                 = */ get_UChar( &c );
1610b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   opcode_base                = get_UChar( &c );
1611b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* skip over "standard_opcode_lengths" */
1612b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 1; i < (Word)opcode_base; i++)
1613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     (void)get_UChar( &c );
1614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* skip over the directory names table */
1616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (peek_UChar(&c) != 0) {
1617b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     (void)get_AsciiZ(&c);
1618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1619b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   (void)get_UChar(&c); /* skip terminating zero */
1620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Read and record the file names table */
1622b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->filenameTable);
1623b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert( VG_(sizeXA)( parser->filenameTable ) == 0 );
1624b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Add a dummy index-zero entry.  DWARF3 numbers its files
1625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      from 1, for some reason. */
1626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   str = ML_(addStr)( cc->di, "<unknown_file>", -1 );
1627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(addToXA)( parser->filenameTable, &str );
1628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (peek_UChar(&c) != 0) {
16295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiCursor cur = get_AsciiZ(&c);
16305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      str = ML_(addStrFromCursor)( cc->di, cur );
1631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("  read_filename_table: %ld %s\n",
1632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               VG_(sizeXA)(parser->filenameTable), str);
1633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(addToXA)( parser->filenameTable, &str );
1634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      (void)get_ULEB128( &c ); /* skip directory index # */
1635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      (void)get_ULEB128( &c ); /* skip last mod time */
1636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      (void)get_ULEB128( &c ); /* file size */
1637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* We're done!  The rest of it is not interesting. */
1639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1641b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1642b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
16439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic void parse_var_DIE (
16449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/WordFM* /* of (XArray* of AddrRange, void) */ rangestree,
16459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/XArray* /* of TempVar* */ tempvars,
16469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/XArray* /* of GExpr* */ gexprs,
16479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/D3VarParser* parser,
16489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   DW_TAG dtag,
16499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   UWord posn,
16509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Int level,
16519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Cursor* c_die,
16529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Cursor* c_abbv,
16539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   CUConst* cc,
16549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Bool td3
16559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj)
1656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
16575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   FormContents cts;
1658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1659b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UWord saved_die_c_offset  = get_position_of_Cursor( c_die );
1660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UWord saved_abbv_c_offset = get_position_of_Cursor( c_abbv );
1661d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   Bool  debug_types_flag;
1662f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   Bool  alt_flag;
1663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1664b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   varstack_preen( parser, td3, level-1 );
1665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1666f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   if (dtag == DW_TAG_compile_unit
1667f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj       || dtag == DW_TAG_type_unit
1668f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj       || dtag == DW_TAG_partial_unit) {
1669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_lo    = False;
1670b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_hi1   = False;
1671de065a05bd7e802669c9074b129268bd9a5c308csewardj      Bool hiIsRelative = False;
1672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_range = False;
1673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr ip_lo    = 0;
1674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr ip_hi1   = 0;
1675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr rangeoff = 0;
1676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
1677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
1678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
1679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
16805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
16815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_low_pc && cts.szB > 0) {
16825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ip_lo   = cts.u.val;
1683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_lo = True;
1684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
16855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_high_pc && cts.szB > 0) {
16865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ip_hi1   = cts.u.val;
1687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_hi1 = True;
1688de065a05bd7e802669c9074b129268bd9a5c308csewardj            if (form != DW_FORM_addr)
1689de065a05bd7e802669c9074b129268bd9a5c308csewardj               hiIsRelative = True;
1690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
16915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_ranges && cts.szB > 0) {
16925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            rangeoff   = cts.u.val;
1693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_range = True;
1694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
16955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_stmt_list && cts.szB > 0) {
16965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            read_filename_table( parser, cc, cts.u.val, td3 );
1697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1699de065a05bd7e802669c9074b129268bd9a5c308csewardj      if (have_lo && have_hi1 && hiIsRelative)
1700de065a05bd7e802669c9074b129268bd9a5c308csewardj         ip_hi1 += ip_lo;
1701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Now, does this give us an opportunity to find this
1702b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         CU's svma? */
1703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#if 0
1704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (level == 0 && have_lo) {
1705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vg_assert(!cc->cu_svma_known); /* if this fails, it must be
1706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         because we've already seen a DW_TAG_compile_unit DIE at level
1707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         0.  But that can't happen, because DWARF3 only allows exactly
1708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         one top level DIE per CU. */
1709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         cc->cu_svma_known = True;
1710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         cc->cu_svma = ip_lo;
1711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (1)
1712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            TRACE_D3("BBBBAAAA acquire CU_SVMA of %p\n", cc->cu_svma);
1713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* Now, it may be that this DIE doesn't tell us the CU's
1714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            SVMA, by way of not having a DW_AT_low_pc.  That's OK --
1715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            the CU doesn't *have* to have its SVMA specified.
1716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            But as per last para D3 spec sec 3.1.1 ("Normal and
1718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Partial Compilation Unit Entries", "If the base address
1719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            (viz, the SVMA) is undefined, then any DWARF entry of
1720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            structure defined interms of the base address of that
1721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            compilation unit is not valid.".  So that means, if whilst
1722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            processing the children of this top level DIE (or their
1723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            children, etc) we see a DW_AT_range, and cu_svma_known is
1724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            False, then the DIE that contains it is (per the spec)
1725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            invalid, and we can legitimately stop and complain. */
1726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1727b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#else
1728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* .. whereas The Reality is, simply assume the SVMA is zero
1729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if it isn't specified. */
1730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (level == 0) {
1731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vg_assert(!cc->cu_svma_known);
1732b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         cc->cu_svma_known = True;
1733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (have_lo)
1734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            cc->cu_svma = ip_lo;
1735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         else
1736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            cc->cu_svma = 0;
1737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
1739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
1740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (have_lo && have_hi1 && (!have_range)) {
1741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (ip_lo < ip_hi1)
1742b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            varstack_push( cc, parser, td3,
1743b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           unitary_range_list(ip_lo, ip_hi1 - 1),
1744b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           level,
1745b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           False/*isFunc*/, NULL/*fbGX*/ );
1746b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
1747b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if ((!have_lo) && (!have_hi1) && have_range) {
1748b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         varstack_push( cc, parser, td3,
1749b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        get_range_list( cc, td3,
1750b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                        rangeoff, cc->cu_svma ),
1751b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        level,
1752b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        False/*isFunc*/, NULL/*fbGX*/ );
1753b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
1754b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if ((!have_lo) && (!have_hi1) && (!have_range)) {
1755b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* CU has no code, presumably? */
1756b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         varstack_push( cc, parser, td3,
1757b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        empty_range_list(),
1758b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        level,
1759b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        False/*isFunc*/, NULL/*fbGX*/ );
1760b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
1761f578a69a862391896fa2f03359c3744022ae9783sewardj      if (have_lo && (!have_hi1) && have_range && ip_lo == 0) {
1762f578a69a862391896fa2f03359c3744022ae9783sewardj         /* broken DIE created by gcc-4.3.X ?  Ignore the
1763f578a69a862391896fa2f03359c3744022ae9783sewardj            apparently-redundant DW_AT_low_pc and use the DW_AT_ranges
1764f578a69a862391896fa2f03359c3744022ae9783sewardj            instead. */
1765f578a69a862391896fa2f03359c3744022ae9783sewardj         varstack_push( cc, parser, td3,
1766f578a69a862391896fa2f03359c3744022ae9783sewardj                        get_range_list( cc, td3,
1767f578a69a862391896fa2f03359c3744022ae9783sewardj                                        rangeoff, cc->cu_svma ),
1768f578a69a862391896fa2f03359c3744022ae9783sewardj                        level,
1769f578a69a862391896fa2f03359c3744022ae9783sewardj                        False/*isFunc*/, NULL/*fbGX*/ );
1770f578a69a862391896fa2f03359c3744022ae9783sewardj      } else {
1771f578a69a862391896fa2f03359c3744022ae9783sewardj         if (0) VG_(printf)("I got hlo %d hhi1 %d hrange %d\n",
1772f578a69a862391896fa2f03359c3744022ae9783sewardj                            (Int)have_lo, (Int)have_hi1, (Int)have_range);
1773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto bad_DIE;
1774f578a69a862391896fa2f03359c3744022ae9783sewardj      }
1775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1777b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_lexical_block || dtag == DW_TAG_subprogram) {
1778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   have_lo    = False;
1779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   have_hi1   = False;
1780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   have_range = False;
1781de065a05bd7e802669c9074b129268bd9a5c308csewardj      Bool   hiIsRelative = False;
1782b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr   ip_lo      = 0;
1783b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr   ip_hi1     = 0;
1784b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr   rangeoff   = 0;
1785b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   isFunc     = dtag == DW_TAG_subprogram;
1786b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GExpr* fbGX       = NULL;
1787b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
1788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
1789b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
1790b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
17915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
17925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_low_pc && cts.szB > 0) {
17935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ip_lo   = cts.u.val;
1794b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_lo = True;
1795b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
17965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_high_pc && cts.szB > 0) {
17975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ip_hi1   = cts.u.val;
1798b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_hi1 = True;
1799de065a05bd7e802669c9074b129268bd9a5c308csewardj            if (form != DW_FORM_addr)
1800de065a05bd7e802669c9074b129268bd9a5c308csewardj               hiIsRelative = True;
1801b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
18025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_ranges && cts.szB > 0) {
18035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            rangeoff   = cts.u.val;
1804b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_range = True;
1805b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1806b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (isFunc
1807b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             && attr == DW_AT_frame_base
18085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             && cts.szB != 0 /* either scalar or nonempty block */) {
18095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            fbGX = get_GX( cc, False/*td3*/, &cts );
1810b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            vg_assert(fbGX);
181159a2d18d0ddfa241850017252b0804d469187d79sewardj            VG_(addToXA)(gexprs, &fbGX);
1812b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1814de065a05bd7e802669c9074b129268bd9a5c308csewardj      if (have_lo && have_hi1 && hiIsRelative)
1815de065a05bd7e802669c9074b129268bd9a5c308csewardj         ip_hi1 += ip_lo;
1816b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
1817b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (dtag == DW_TAG_subprogram
1818b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          && (!have_lo) && (!have_hi1) && (!have_range)) {
1819b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* This is legit - ignore it. Sec 3.3.3: "A subroutine entry
1820b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            representing a subroutine declaration that is not also a
1821b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            definition does not have code address or range
1822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            attributes." */
1823b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
1824b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (dtag == DW_TAG_lexical_block
1825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          && (!have_lo) && (!have_hi1) && (!have_range)) {
1826b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* I believe this is legit, and means the lexical block
1827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            contains no insns (whatever that might mean).  Ignore. */
1828b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
1829b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (have_lo && have_hi1 && (!have_range)) {
1830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* This scope supplies just a single address range. */
1831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (ip_lo < ip_hi1)
1832b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            varstack_push( cc, parser, td3,
1833b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           unitary_range_list(ip_lo, ip_hi1 - 1),
1834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           level, isFunc, fbGX );
1835b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
1836b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if ((!have_lo) && (!have_hi1) && have_range) {
1837b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* This scope supplies multiple address ranges via the use of
1838b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            a range list. */
1839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         varstack_push( cc, parser, td3,
1840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        get_range_list( cc, td3,
1841b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                        rangeoff, cc->cu_svma ),
1842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        level, isFunc, fbGX );
1843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
1844b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (have_lo && (!have_hi1) && (!have_range)) {
1845b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* This scope is bogus.  The D3 spec sec 3.4 (Lexical Block
1846b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Entries) says fairly clearly that a scope must have either
1847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            _range or (_low_pc and _high_pc). */
1848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* The spec is a bit ambiguous though.  Perhaps a single byte
1849b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            range is intended?  See sec 2.17 (Code Addresses And Ranges) */
1850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* This case is here because icc9 produced this:
1851b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         <2><13bd>: DW_TAG_lexical_block
1852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            DW_AT_decl_line   : 5229
1853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            DW_AT_decl_column : 37
1854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            DW_AT_decl_file   : 1
1855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            DW_AT_low_pc      : 0x401b03
1856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         */
1857b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* Ignore (seems safe than pushing a single byte range) */
1858b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
1859b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto bad_DIE;
1860b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1862b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_variable || dtag == DW_TAG_formal_parameter) {
18631636d33c13958b9c0e7d3059cdd5005746418eb2florian      HChar* name        = NULL;
18649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      UWord  typeR       = D3_INVALID_CUOFF;
186581d24c396c66dde7db2d9b567451f99081a2eab7philippe      Bool   global      = False;
1866b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GExpr* gexpr       = NULL;
1867b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int    n_attrs     = 0;
1868b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord  abs_ori     = (UWord)D3_INVALID_CUOFF;
1869b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int    lineNo      = 0;
18701636d33c13958b9c0e7d3059cdd5005746418eb2florian      HChar* fileName    = NULL;
1871b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
1872b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
1873b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
1874b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
18755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
1876b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         n_attrs++;
18775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
18785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            name = ML_(addStrFromCursor)( cc->di, cts.u.cur );
1879b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1880b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == DW_AT_location
18815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             && cts.szB != 0 /* either scalar or nonempty block */) {
18825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            gexpr = get_GX( cc, False/*td3*/, &cts );
1883b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            vg_assert(gexpr);
188459a2d18d0ddfa241850017252b0804d469187d79sewardj            VG_(addToXA)(gexprs, &gexpr);
1885b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
18865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_type && cts.szB > 0) {
18875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeR = cook_die_using_form( cc, cts.u.val, form );
1888b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
18895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_external && cts.szB > 0 && cts.u.val > 0) {
189081d24c396c66dde7db2d9b567451f99081a2eab7philippe            global = True;
1891b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
18925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_abstract_origin && cts.szB > 0) {
18935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            abs_ori = (UWord)cts.u.val;
1894b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
18955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_declaration && cts.szB > 0 && cts.u.val > 0) {
18964c245e595b9f6300d3120408ca873f7115d9cc7dnjn            /*declaration = True;*/
1897b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
18985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_decl_line && cts.szB > 0) {
18995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            lineNo = (Int)cts.u.val;
1900b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
19015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_decl_file && cts.szB > 0) {
19025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            Int ftabIx = (Int)cts.u.val;
1903b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (ftabIx >= 1
1904b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                && ftabIx < VG_(sizeXA)( parser->filenameTable )) {
19051636d33c13958b9c0e7d3059cdd5005746418eb2florian               fileName = *(HChar**)
1906b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                          VG_(indexXA)( parser->filenameTable, ftabIx );
1907b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               vg_assert(fileName);
1908b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
1909b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (0) VG_(printf)("XXX filename = %s\n", fileName);
1910b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1911b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
191281d24c396c66dde7db2d9b567451f99081a2eab7philippe      if (!global && dtag == DW_TAG_variable && level == 1) {
191381d24c396c66dde7db2d9b567451f99081a2eab7philippe         /* Case of a static variable. It is better to declare
191481d24c396c66dde7db2d9b567451f99081a2eab7philippe            it global as the variable is not really related to
191581d24c396c66dde7db2d9b567451f99081a2eab7philippe            a PC range, as its address can be used by program
191681d24c396c66dde7db2d9b567451f99081a2eab7philippe            counters outside of the ranges where it is visible . */
191781d24c396c66dde7db2d9b567451f99081a2eab7philippe         global = True;
191881d24c396c66dde7db2d9b567451f99081a2eab7philippe      }
191981d24c396c66dde7db2d9b567451f99081a2eab7philippe
1920b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* We'll collect it under if one of the following three
1921b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         conditions holds:
1922b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (1) has location and type    -> completed
1923b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (2) has type only            -> is an abstract instance
1924b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (3) has location and abs_ori -> is a concrete instance
19259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         Name, filename and line number are all optional frills.
1926b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      */
1927b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if ( /* 1 */ (gexpr && typeR != D3_INVALID_CUOFF)
1928b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           /* 2 */ || (typeR != D3_INVALID_CUOFF)
1929b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           /* 3 */ || (gexpr && abs_ori != (UWord)D3_INVALID_CUOFF) ) {
1930b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1931b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* Add this variable to the list of interesting looking
1932b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            variables.  Crucially, note along with it the address
1933b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            range(s) associated with the variable, which for locals
1934b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            will be the address ranges at the top of the varparser's
1935b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            stack. */
1936b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         GExpr*   fbGX = NULL;
1937b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Word     i, nRanges;
1938b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         XArray*  /* of AddrRange */ xa;
1939b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TempVar* tv;
1940b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* Stack can't be empty; we put a dummy entry on it for the
1941b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            entire address range before starting with the DIEs for
1942b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            this CU. */
1943b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vg_assert(parser->sp >= 0);
1944b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
194581d24c396c66dde7db2d9b567451f99081a2eab7philippe         /* If this is a local variable (non-global), try to find
1946b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            the GExpr for the DW_AT_frame_base of the containing
1947b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            function.  It should have been pushed on the stack at the
1948b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            time we encountered its DW_TAG_subprogram DIE, so the way
1949b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            to find it is to scan back down the stack looking for it.
1950b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            If there isn't an enclosing stack entry marked 'isFunc'
1951b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            then we must be seeing variable or formal param DIEs
1952b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            outside of a function, so we deem the Dwarf to be
1953b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            malformed if that happens.  Note that the fbGX may be NULL
1954b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if the containing DT_TAG_subprogram didn't supply a
1955b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            DW_AT_frame_base -- that's OK, but there must actually be
1956b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            a containing DW_TAG_subprogram. */
195781d24c396c66dde7db2d9b567451f99081a2eab7philippe         if (!global) {
1958b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Bool found = False;
1959b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            for (i = parser->sp; i >= 0; i--) {
1960b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (parser->isFunc[i]) {
1961b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  fbGX = parser->fbGX[i];
1962b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  found = True;
1963b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  break;
1964b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               }
1965b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
1966b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (!found) {
1967b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (0 && VG_(clo_verbosity) >= 0) {
1968b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  VG_(message)(Vg_DebugMsg,
196981d24c396c66dde7db2d9b567451f99081a2eab7philippe                     "warning: parse_var_DIE: non-global variable "
1970738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                     "outside DW_TAG_subprogram\n");
1971b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               }
1972b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               /* goto bad_DIE; */
1973b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               /* This seems to happen a lot.  Just ignore it -- if,
1974b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  when we come to evaluation of the location (guarded)
1975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  expression, it requires a frame base value, and
1976b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  there's no expression for that, then evaluation as a
1977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  whole will fail.  Harmless - a bit of a waste of
1978b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  cycles but nothing more. */
1979b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
1980b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1981b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
198281d24c396c66dde7db2d9b567451f99081a2eab7philippe         /* re "global ? 0 : parser->sp" (twice), if the var is
198381d24c396c66dde7db2d9b567451f99081a2eab7philippe            marked 'global' then we must put it at the global scope,
1984b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            as only the global scope (level 0) covers the entire PC
1985b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            address space.  It is asserted elsewhere that level 0
1986b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            always covers the entire address space. */
198781d24c396c66dde7db2d9b567451f99081a2eab7philippe         xa = parser->ranges[global ? 0 : parser->sp];
1988b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         nRanges = VG_(sizeXA)(xa);
1989b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vg_assert(nRanges >= 0);
1990b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
19919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         tv = ML_(dinfo_zalloc)( "di.readdwarf3.pvD.1", sizeof(TempVar) );
1992b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->name   = name;
199381d24c396c66dde7db2d9b567451f99081a2eab7philippe         tv->level  = global ? 0 : parser->sp;
1994b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->typeR  = typeR;
1995b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->gexpr  = gexpr;
1996b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->fbGX   = fbGX;
1997b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->fName  = fileName;
1998b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->fLine  = lineNo;
1999b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->dioff  = posn;
2000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->absOri = abs_ori;
2001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* See explanation on definition of type TempVar for the
2003b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            reason for this elaboration. */
2004b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->nRanges = nRanges;
2005b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->rngOneMin = 0;
2006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->rngOneMax = 0;
2007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->rngMany = NULL;
2008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (nRanges == 1) {
2009b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            AddrRange* range = VG_(indexXA)(xa, 0);
2010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            tv->rngOneMin = range->aMin;
2011b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            tv->rngOneMax = range->aMax;
2012b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2013b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         else if (nRanges > 1) {
20149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            /* See if we already have a range list which is
20159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               structurally identical.  If so, use that; if not, clone
20169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               this one, and add it to our collection. */
20179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            UWord keyW, valW;
20189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            if (VG_(lookupFM)( rangestree, &keyW, &valW, (UWord)xa )) {
20199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               XArray* old = (XArray*)keyW;
20209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               tl_assert(valW == 0);
20219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               tl_assert(old != xa);
20229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               tv->rngMany = old;
20239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            } else {
20249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               XArray* cloned = VG_(cloneXA)( "di.readdwarf3.pvD.2", xa );
20259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               tv->rngMany = cloned;
20269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               VG_(addToFM)( rangestree, (UWord)cloned, 0 );
20279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            }
2028b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
203059a2d18d0ddfa241850017252b0804d469187d79sewardj         VG_(addToXA)( tempvars, &tv );
2031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("  Recording this variable, with %ld PC range(s)\n",
2033b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  VG_(sizeXA)(xa) );
2034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* collect stats on how effective the ->ranges special
2035b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            casing is */
2036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (0) {
20379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            static Int ntot=0, ngt=0;
20389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            ntot++;
20399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            if (tv->rngMany) ngt++;
20409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            if (0 == (ntot % 100000))
20419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               VG_(printf)("XXXX %d tot, %d cloned\n", ntot, ngt);
2042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2044b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2046b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Here are some other weird cases seen in the wild:
2047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2048b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            We have a variable with a name and a type, but no
2049b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            location.  I guess that's a sign that it has been
2050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            optimised away.  Ignore it.  Here's an example:
2051b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2052b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            static Int lc_compar(void* n1, void* n2) {
2053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               MC_Chunk* mc1 = *(MC_Chunk**)n1;
2054b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               MC_Chunk* mc2 = *(MC_Chunk**)n2;
2055b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               return (mc1->data < mc2->data ? -1 : 1);
2056b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
2057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Both mc1 and mc2 are like this
2059b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            <2><5bc>: Abbrev Number: 21 (DW_TAG_variable)
2060b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_name        : mc1
2061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_decl_file   : 1
2062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_decl_line   : 216
2063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_type        : <5d3>
2064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2065b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            whereas n1 and n2 do have locations specified.
2066b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ---------------------------------------------
2068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2069b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            We see a DW_TAG_formal_parameter with a type, but
2070b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            no name and no location.  It's probably part of a function type
2071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            construction, thusly, hence ignore it:
2072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         <1><2b4>: Abbrev Number: 12 (DW_TAG_subroutine_type)
2073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_sibling     : <2c9>
2074b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_prototyped  : 1
2075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_type        : <114>
2076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         <2><2be>: Abbrev Number: 13 (DW_TAG_formal_parameter)
2077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_type        : <13e>
2078b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         <2><2c3>: Abbrev Number: 13 (DW_TAG_formal_parameter)
2079b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_type        : <133>
2080b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2081b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ---------------------------------------------
2082b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2083b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Is very minimal, like this:
2084b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            <4><81d>: Abbrev Number: 44 (DW_TAG_variable)
2085b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_abstract_origin: <7ba>
2086b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            What that signifies I have no idea.  Ignore.
2087b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2088b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ----------------------------------------------
2089b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2090b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Is very minimal, like this:
2091b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            <200f>: DW_TAG_formal_parameter
2092b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_abstract_ori: <1f4c>
2093b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_location    : 13440
2094b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            What that signifies I have no idea.  Ignore.
2095b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            It might be significant, though: the variable at least
2096b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            has a location and so might exist somewhere.
2097b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Maybe we should handle this.
2098b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ---------------------------------------------
2100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            <22407>: DW_TAG_variable
2102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              DW_AT_name        : (indirect string, offset: 0x6579):
2103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                  vgPlain_trampoline_stuff_start
2104b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              DW_AT_decl_file   : 29
2105b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              DW_AT_decl_line   : 56
2106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              DW_AT_external    : 1
2107b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              DW_AT_declaration : 1
2108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2109b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Nameless and typeless variable that has a location?  Who
2110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            knows.  Not me.
2111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            <2><3d178>: Abbrev Number: 22 (DW_TAG_variable)
2112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                 DW_AT_location    : 9 byte block: 3 c0 c7 13 38 0 0 0 0
2113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                     (DW_OP_addr: 3813c7c0)
2114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            No, really.  Check it out.  gcc is quite simply borked.
2116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            <3><168cc>: Abbrev Number: 141 (DW_TAG_variable)
2117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            // followed by no attributes, and the next DIE is a sibling,
2118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            // not a child
2119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            */
2120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return;
2122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  bad_DIE:
2124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   set_position_of_Cursor( c_die,  saved_die_c_offset );
2125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   set_position_of_Cursor( c_abbv, saved_abbv_c_offset );
2126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(printf)("\nparse_var_DIE: confused by:\n");
2127f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   posn = uncook_die( cc, posn, &debug_types_flag, &alt_flag );
2128d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   VG_(printf)(" <%d><%lx>: %s", level, posn, ML_(pp_DW_TAG)( dtag ) );
2129d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   if (debug_types_flag) {
2130d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      VG_(printf)(" (in .debug_types)");
2131d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   }
2132f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   else if (alt_flag) {
2133f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      VG_(printf)(" (in alternate .debug_info)");
2134f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   }
2135d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   VG_(printf)("\n");
2136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
2137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (attr == 0 && form == 0) break;
2140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(printf)("     %18s: ", ML_(pp_DW_AT)(attr));
2141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Get the form contents, so as to print them */
21425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      get_Form_contents( &cts, cc, c_die, True, form );
2143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(printf)("\t\n");
2144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(printf)("\n");
2146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   cc->barf("parse_var_DIE: confused by the above DIE");
2147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
2148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
2152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
2153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Parsing of type-related DIEs                         ---*/
2154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
2155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
2156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define N_D3_TYPE_STACK 16
2158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
2160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct {
21612acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      /* What source language?  'A'=Ada83/95,
21622acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj                                'C'=C/C++,
21632acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj                                'F'=Fortran,
21642acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj                                '?'=other
2165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Established once per compilation unit. */
2166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar language;
2167b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* A stack of types which are currently under construction */
2168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int   sp; /* [sp] is innermost active entry; sp==-1 for empty
2169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   stack */
21709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* Note that the TyEnts in qparentE are temporary copies of the
21719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ones accumulating in the main tyent array.  So it is not safe
21729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         to free up anything on them when popping them off the stack
21739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         (iow, it isn't safe to use TyEnt__make_EMPTY on them).  Just
21749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         memset them to zero when done. */
21759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TyEnt qparentE[N_D3_TYPE_STACK]; /* parent TyEnts */
2176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int   qlevel[N_D3_TYPE_STACK];
2177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   D3TypeParser;
2180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
21816bd9dc18c043927c1196caba20a327238a179c42florianstatic void typestack_show ( D3TypeParser* parser, const HChar* str ) {
2182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Word i;
2183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(printf)("  typestack (%s) {\n", str);
2184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i <= parser->sp; i++) {
2185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(printf)("    [%ld] (level %d): ", i, parser->qlevel[i]);
21869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      ML_(pp_TyEnt)( &parser->qparentE[i] );
2187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(printf)("\n");
2188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(printf)("  }\n");
2190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2192b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Remove from the stack, all entries with .level > 'level' */
2193b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
2194b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid typestack_preen ( D3TypeParser* parser, Bool td3, Int level )
2195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
2196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool changed = False;
2197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp < N_D3_TYPE_STACK);
2198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
2199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(parser->sp >= -1);
2200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (parser->sp == -1) break;
2201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (parser->qlevel[parser->sp] <= level) break;
2202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (0)
2203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("BBBBAAAA typestack_pop [newsp=%d]\n", parser->sp-1);
22049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
22059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&parser->qparentE[parser->sp], 0, sizeof(TyEnt));
22069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      parser->qparentE[parser->sp].cuOff = D3_INVALID_CUOFF;
22079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      parser->qparentE[parser->sp].tag = Te_EMPTY;
22089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      parser->qlevel[parser->sp] = 0;
2209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parser->sp--;
2210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      changed = True;
2211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (changed && td3)
2213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      typestack_show( parser, "after preen" );
2214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool typestack_is_empty ( D3TypeParser* parser ) {
2217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp >= -1 && parser->sp < N_D3_TYPE_STACK);
2218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return parser->sp == -1;
2219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void typestack_push ( CUConst* cc,
2222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             D3TypeParser* parser,
2223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             Bool td3,
22249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                             TyEnt* parentE, Int level ) {
2225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (0)
22269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TRACE_D3("BBBBAAAA typestack_push[newsp=%d]: %d  %05lx\n",
22279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            parser->sp+1, level, parentE->cuOff);
2228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* First we need to zap everything >= 'level', as we are about to
2230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      replace any previous entry at 'level', so .. */
2231b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   typestack_preen(parser, /*td3*/False, level-1);
2232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp >= -1);
2234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp < N_D3_TYPE_STACK);
2235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (parser->sp == N_D3_TYPE_STACK-1)
2236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("typestack_push: N_D3_TYPE_STACK is too low; "
2237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               "increase and recompile");
2238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (parser->sp >= 0)
2239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(parser->qlevel[parser->sp] < level);
2240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->sp++;
22419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(parser->qparentE[parser->sp].tag == Te_EMPTY);
2242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->qlevel[parser->sp]  == 0);
22439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(parentE);
22449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(ML_(TyEnt__is_type)(parentE));
22459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(parentE->cuOff != D3_INVALID_CUOFF);
22469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   parser->qparentE[parser->sp] = *parentE;
2247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->qlevel[parser->sp]  = level;
2248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (td3)
2249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      typestack_show( parser, "after push" );
2250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
22522acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj/* True if the subrange type being parsed gives the bounds of an array. */
22532acc87cac77cedb3884e9e3a5188bac6edda5aeesewardjstatic Bool subrange_type_denotes_array_bounds ( D3TypeParser* parser,
22542acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj                                                 DW_TAG dtag ) {
22552acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   vg_assert(dtag == DW_TAG_subrange_type);
22562acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   /* For most languages, a subrange_type dtag always gives the
22572acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      bounds of an array.
22582acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      For Ada, there are additional conditions as a subrange_type
22592acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      is also used for other purposes. */
22602acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   if (parser->language != 'A')
22612acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      /* not Ada, so it definitely denotes an array bound. */
22622acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      return True;
22632acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   else
22642acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      /* Extra constraints for Ada: it only denotes an array bound if .. */
22652acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      return (! typestack_is_empty(parser)
22662acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj              && parser->qparentE[parser->sp].tag == Te_TyArray);
22672acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj}
2268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Parse a type-related DIE.  'parser' holds the current parser state.
2270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   'admin' is where the completed types are dumped.  'dtag' is the tag
2271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for this DIE.  'c_die' points to the start of the data fields (FORM
2272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   stuff) for the DIE.  c_abbv points to the start of the (name,form)
2273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   pairs which describe the DIE.
2274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   We may find the DIE uninteresting, in which case we should ignore
2276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   it.
22779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
22789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   What happens: the DIE is examined.  If uninteresting, it is ignored.
22799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Otherwise, the DIE gives rise to two things:
22809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
22819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   (1) the offset of this DIE in the CU -- the cuOffset, a UWord
22829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   (2) a TyAdmin structure, which holds the type, or related stuff
22839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
22849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   (2) is added at the end of 'tyadmins', at some index, say 'i'.
22859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
22869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   A pair (cuOffset, i) is added to 'tydict'.
22879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
22889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Hence 'tyadmins' holds the actual type entities, and 'tydict' holds
22899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   a mapping from cuOffset to the index of the corresponding entry in
22909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   'tyadmin'.
22919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
22929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   When resolving a cuOffset to a TyAdmin, first look up the cuOffset
22939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   in the tydict (by binary search).  This gives an index into
22949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   tyadmins, and the required entity lives in tyadmins at that index.
2295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/
2296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
22979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents,
2298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             /*MOD*/D3TypeParser* parser,
2299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             DW_TAG dtag,
2300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             UWord posn,
2301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             Int level,
2302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             Cursor* c_die,
2303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             Cursor* c_abbv,
2304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             CUConst* cc,
2305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             Bool td3 )
2306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
23075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   FormContents cts;
23089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEnt typeE;
23099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEnt atomE;
23109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEnt fieldE;
23119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEnt boundE;
2312d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   Bool  debug_types_flag;
2313f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   Bool  alt_flag;
2314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UWord saved_die_c_offset  = get_position_of_Cursor( c_die );
2316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UWord saved_abbv_c_offset = get_position_of_Cursor( c_abbv );
2317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
23189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(memset)( &typeE,  0xAA, sizeof(typeE) );
23199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(memset)( &atomE,  0xAA, sizeof(atomE) );
23209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(memset)( &fieldE, 0xAA, sizeof(fieldE) );
23219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(memset)( &boundE, 0xAA, sizeof(boundE) );
23229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
2323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* If we've returned to a level at or above any previously noted
2324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parent, un-note it, so we don't believe we're still collecting
2325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      its children. */
2326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   typestack_preen( parser, td3, level-1 );
2327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2328f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   if (dtag == DW_TAG_compile_unit
2329f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj       || dtag == DW_TAG_type_unit
2330f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj       || dtag == DW_TAG_partial_unit) {
2331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* See if we can find DW_AT_language, since it is important for
2332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         establishing array bounds (see DW_TAG_subrange_type below in
2333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         this fn) */
2334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
23385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
2339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr != DW_AT_language)
2340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            continue;
23415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (cts.szB <= 0)
2342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           goto bad_DIE;
23435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         switch (cts.u.val) {
2344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_C89: case DW_LANG_C:
2345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_C_plus_plus: case DW_LANG_ObjC:
2346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_ObjC_plus_plus: case DW_LANG_UPC:
2347fba428cd266b8a39db641c5fd9523daa8939bed0tom            case DW_LANG_Upc: case DW_LANG_C99:
2348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               parser->language = 'C'; break;
2349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_Fortran77: case DW_LANG_Fortran90:
2350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_Fortran95:
2351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               parser->language = 'F'; break;
23522acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj            case DW_LANG_Ada83: case DW_LANG_Ada95:
23532acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj               parser->language = 'A'; break;
23542acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj            case DW_LANG_Cobol74:
2355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_Cobol85: case DW_LANG_Pascal83:
2356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_Modula2: case DW_LANG_Java:
23572acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj            case DW_LANG_PLI:
2358fba428cd266b8a39db641c5fd9523daa8939bed0tom            case DW_LANG_D: case DW_LANG_Python:
2359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_Mips_Assembler:
2360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               parser->language = '?'; break;
2361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            default:
2362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               goto bad_DIE;
2363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_base_type) {
2368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* We can pick up a new base type any time. */
23699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
23709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = D3_INVALID_CUOFF;
23719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyBase;
2372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
23765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
23775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
23789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            typeE.Te.TyBase.name
23795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = ML_(cur_read_strdup)( cts.u.cur,
23805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       "di.readdwarf3.ptD.base_type.1" );
2381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
23825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_byte_size && cts.szB > 0) {
23835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyBase.szB = cts.u.val;
2384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
23855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_encoding && cts.szB > 0) {
23865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            switch (cts.u.val) {
2387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               case DW_ATE_unsigned: case DW_ATE_unsigned_char:
238850c5093772c2b23fd0897d3590dcfaec1c92ac83tom               case DW_ATE_UTF: /* since DWARF4, e.g. char16_t from C++ */
2389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               case DW_ATE_boolean:/* FIXME - is this correct? */
23905db15403e889d4db339b342bc2a824ef0bfaa654sewardj               case DW_ATE_unsigned_fixed:
23919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                  typeE.Te.TyBase.enc = 'U'; break;
2392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               case DW_ATE_signed: case DW_ATE_signed_char:
23935db15403e889d4db339b342bc2a824ef0bfaa654sewardj               case DW_ATE_signed_fixed:
23949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                  typeE.Te.TyBase.enc = 'S'; break;
2395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               case DW_ATE_float:
23969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                  typeE.Te.TyBase.enc = 'F'; break;
2397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               case DW_ATE_complex_float:
23989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                  typeE.Te.TyBase.enc = 'C'; break;
2399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               default:
2400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  goto bad_DIE;
2401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
2402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Invent a name if it doesn't have one.  gcc-4.3
2406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         -ftree-vectorize is observed to emit nameless base types. */
24079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (!typeE.Te.TyBase.name)
24089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         typeE.Te.TyBase.name
24099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = ML_(dinfo_strdup)( "di.readdwarf3.ptD.base_type.2",
24109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                 "<anon_base_type>" );
2411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
2413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (/* must have a name */
24149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj          typeE.Te.TyBase.name == NULL
2415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          /* and a plausible size.  Yes, really 32: "complex long
2416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             double" apparently has size=32 */
24179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj          || typeE.Te.TyBase.szB < 0 || typeE.Te.TyBase.szB > 32
2418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          /* and a plausible encoding */
24199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj          || (typeE.Te.TyBase.enc != 'U'
24209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj              && typeE.Te.TyBase.enc != 'S'
24219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj              && typeE.Te.TyBase.enc != 'F'
24229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj              && typeE.Te.TyBase.enc != 'C'))
2423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto bad_DIE;
2424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Last minute hack: if we see this
2425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         <1><515>: DW_TAG_base_type
2426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_byte_size   : 0
2427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_encoding    : 5
2428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_name        : void
2429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         convert it into a real Void type. */
24309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (typeE.Te.TyBase.szB == 0
24319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj          && 0 == VG_(strcmp)("void", typeE.Te.TyBase.name)) {
24329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ML_(TyEnt__make_EMPTY)(&typeE);
24339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         typeE.tag = Te_TyVoid;
24349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         typeE.Te.TyVoid.isFake = False; /* it's a real one! */
2435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
24369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
2437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      goto acquire_Type;
2438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
24400e947cfedebda6da2e84fb61af431db5cf1275fcbart   /*
24410e947cfedebda6da2e84fb61af431db5cf1275fcbart    * An example of DW_TAG_rvalue_reference_type:
24420e947cfedebda6da2e84fb61af431db5cf1275fcbart    *
24430e947cfedebda6da2e84fb61af431db5cf1275fcbart    * $ readelf --debug-dump /usr/lib/debug/usr/lib/libstdc++.so.6.0.16.debug
24440e947cfedebda6da2e84fb61af431db5cf1275fcbart    *  <1><1014>: Abbrev Number: 55 (DW_TAG_rvalue_reference_type)
24450e947cfedebda6da2e84fb61af431db5cf1275fcbart    *     <1015>   DW_AT_byte_size   : 4
24460e947cfedebda6da2e84fb61af431db5cf1275fcbart    *     <1016>   DW_AT_type        : <0xe52>
24470e947cfedebda6da2e84fb61af431db5cf1275fcbart    */
2448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_pointer_type || dtag == DW_TAG_reference_type
24490e947cfedebda6da2e84fb61af431db5cf1275fcbart       || dtag == DW_TAG_ptr_to_member_type
24500e947cfedebda6da2e84fb61af431db5cf1275fcbart       || dtag == DW_TAG_rvalue_reference_type) {
2451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* This seems legit for _pointer_type and _reference_type.  I
2452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         don't know if rolling _ptr_to_member_type in here really is
2453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         legit, but it's better than not handling it at all. */
24549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
24559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = D3_INVALID_CUOFF;
24560e947cfedebda6da2e84fb61af431db5cf1275fcbart      switch (dtag) {
24570e947cfedebda6da2e84fb61af431db5cf1275fcbart      case DW_TAG_pointer_type:
24580e947cfedebda6da2e84fb61af431db5cf1275fcbart         typeE.tag = Te_TyPtr;
24590e947cfedebda6da2e84fb61af431db5cf1275fcbart         break;
24600e947cfedebda6da2e84fb61af431db5cf1275fcbart      case DW_TAG_reference_type:
24610e947cfedebda6da2e84fb61af431db5cf1275fcbart         typeE.tag = Te_TyRef;
24620e947cfedebda6da2e84fb61af431db5cf1275fcbart         break;
24630e947cfedebda6da2e84fb61af431db5cf1275fcbart      case DW_TAG_ptr_to_member_type:
24640e947cfedebda6da2e84fb61af431db5cf1275fcbart         typeE.tag = Te_TyPtrMbr;
24650e947cfedebda6da2e84fb61af431db5cf1275fcbart         break;
24660e947cfedebda6da2e84fb61af431db5cf1275fcbart      case DW_TAG_rvalue_reference_type:
24670e947cfedebda6da2e84fb61af431db5cf1275fcbart         typeE.tag = Te_TyRvalRef;
24680e947cfedebda6da2e84fb61af431db5cf1275fcbart         break;
24690e947cfedebda6da2e84fb61af431db5cf1275fcbart      default:
24700e947cfedebda6da2e84fb61af431db5cf1275fcbart         vg_assert(False);
24710e947cfedebda6da2e84fb61af431db5cf1275fcbart      }
2472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* target type defaults to void */
24739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyPorR.typeR = D3_FAKEVOID_CUOFF;
24740e947cfedebda6da2e84fb61af431db5cf1275fcbart      /* These four type kinds don't *have* to specify their size, in
247531452303b095a76295b08096b2840276db808b81sewardj         which case we assume it's a machine word.  But if they do
247631452303b095a76295b08096b2840276db808b81sewardj         specify it, it must be a machine word :-)  This probably
247731452303b095a76295b08096b2840276db808b81sewardj         assumes that the word size of the Dwarf3 we're reading is the
247831452303b095a76295b08096b2840276db808b81sewardj         same size as that on the machine.  gcc appears to give a size
247931452303b095a76295b08096b2840276db808b81sewardj         whereas icc9 doesn't. */
248031452303b095a76295b08096b2840276db808b81sewardj      typeE.Te.TyPorR.szB = sizeof(UWord);
2481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2482b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
24855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
24865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_byte_size && cts.szB > 0) {
24875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyPorR.szB = cts.u.val;
2488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
24895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_type && cts.szB > 0) {
24905d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyPorR.typeR
24915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = cook_die_using_form( cc, (UWord)cts.u.val, form );
2492b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2493b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2494b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
249531452303b095a76295b08096b2840276db808b81sewardj      if (typeE.Te.TyPorR.szB != sizeof(UWord))
2496b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto bad_DIE;
2497b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      else
2498b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto acquire_Type;
2499b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2500b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2501b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_enumeration_type) {
2502b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Create a new Type to hold the results. */
25039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
25049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = posn;
25059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyEnum;
25069d82d0f293c83ff2b8c3ab07065d8454059452bemjw      Bool is_decl = False;
25079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyEnum.atomRs
25089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ptD.enum_type.1",
25099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                       ML_(dinfo_free),
25109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                       sizeof(UWord) );
2511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2513b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2514b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
25155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
25165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
25179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            typeE.Te.TyEnum.name
25185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = ML_(cur_read_strdup)( cts.u.cur,
25195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       "di.readdwarf3.pTD.enum_type.2" );
2520b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
25215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_byte_size && cts.szB > 0) {
25225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyEnum.szB = cts.u.val;
2523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
25249d82d0f293c83ff2b8c3ab07065d8454059452bemjw         if (attr == DW_AT_declaration) {
25259d82d0f293c83ff2b8c3ab07065d8454059452bemjw            is_decl = True;
25269d82d0f293c83ff2b8c3ab07065d8454059452bemjw         }
2527b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
25286ece231961274337eb8303aba3ac5247fc7d1ef9sewardj
25296ece231961274337eb8303aba3ac5247fc7d1ef9sewardj      if (!typeE.Te.TyEnum.name)
25306ece231961274337eb8303aba3ac5247fc7d1ef9sewardj         typeE.Te.TyEnum.name
25316ece231961274337eb8303aba3ac5247fc7d1ef9sewardj            = ML_(dinfo_strdup)( "di.readdwarf3.pTD.enum_type.3",
25326ece231961274337eb8303aba3ac5247fc7d1ef9sewardj                                 "<anon_enum_type>" );
25336ece231961274337eb8303aba3ac5247fc7d1ef9sewardj
2534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
25352acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      if (typeE.Te.TyEnum.szB == 0
25362acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj          /* we must know the size */
25372acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj          /* but not for Ada, which uses such dummy
25389d82d0f293c83ff2b8c3ab07065d8454059452bemjw             enumerations as helper for gdb ada mode.
25399d82d0f293c83ff2b8c3ab07065d8454059452bemjw             Also GCC allows incomplete enums as GNU extension.
25409d82d0f293c83ff2b8c3ab07065d8454059452bemjw             http://gcc.gnu.org/onlinedocs/gcc/Incomplete-Enums.html
25419d82d0f293c83ff2b8c3ab07065d8454059452bemjw             These are marked as DW_AT_declaration and won't have
25429d82d0f293c83ff2b8c3ab07065d8454059452bemjw             a size. They can only be used in declaration or as
25439d82d0f293c83ff2b8c3ab07065d8454059452bemjw             pointer types.  You can't allocate variables or storage
25449d82d0f293c83ff2b8c3ab07065d8454059452bemjw             using such an enum type. (Also GCC seems to have a bug
25459d82d0f293c83ff2b8c3ab07065d8454059452bemjw             that will put such an enumeration_type into a .debug_types
25469d82d0f293c83ff2b8c3ab07065d8454059452bemjw             unit which should only contain complete types.) */
25479d82d0f293c83ff2b8c3ab07065d8454059452bemjw          && (parser->language != 'A' && !is_decl)) {
25489d82d0f293c83ff2b8c3ab07065d8454059452bemjw         goto bad_DIE;
2549d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      }
2550d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
2551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* On't stack! */
25529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typestack_push( cc, parser, td3, &typeE, level );
2553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      goto acquire_Type;
2554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2556f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj   /* gcc (GCC) 4.4.0 20081017 (experimental) occasionally produces
2557f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      DW_TAG_enumerator with only a DW_AT_name but no
2558f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      DW_AT_const_value.  This is in violation of the Dwarf3 standard,
2559f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      and appears to be a new "feature" of gcc - versions 4.3.x and
2560f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      earlier do not appear to do this.  So accept DW_TAG_enumerator
2561f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      which only have a name but no value.  An example:
2562f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj
2563f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      <1><180>: Abbrev Number: 6 (DW_TAG_enumeration_type)
2564f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <181>   DW_AT_name        : (indirect string, offset: 0xda70):
2565f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj                                     QtMsgType
2566f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <185>   DW_AT_byte_size   : 4
2567f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <186>   DW_AT_decl_file   : 14
2568f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <187>   DW_AT_decl_line   : 1480
2569f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <189>   DW_AT_sibling     : <0x1a7>
2570f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      <2><18d>: Abbrev Number: 7 (DW_TAG_enumerator)
2571f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <18e>   DW_AT_name        : (indirect string, offset: 0x9e18):
2572f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj                                     QtDebugMsg
2573f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      <2><192>: Abbrev Number: 7 (DW_TAG_enumerator)
2574f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <193>   DW_AT_name        : (indirect string, offset: 0x1505f):
2575f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj                                     QtWarningMsg
2576f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      <2><197>: Abbrev Number: 7 (DW_TAG_enumerator)
2577f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <198>   DW_AT_name        : (indirect string, offset: 0x16f4a):
2578f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj                                     QtCriticalMsg
2579f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      <2><19c>: Abbrev Number: 7 (DW_TAG_enumerator)
2580f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <19d>   DW_AT_name        : (indirect string, offset: 0x156dd):
2581f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj                                     QtFatalMsg
2582f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      <2><1a1>: Abbrev Number: 7 (DW_TAG_enumerator)
2583f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <1a2>   DW_AT_name        : (indirect string, offset: 0x13660):
2584f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj                                     QtSystemMsg
2585f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj   */
2586b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_enumerator) {
25879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)( &atomE, 0, sizeof(atomE) );
25889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      atomE.cuOff = posn;
25899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      atomE.tag   = Te_Atom;
2590b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2591b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2592b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
25945d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
25955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
25969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            atomE.Te.Atom.name
25975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj              = ML_(cur_read_strdup)( cts.u.cur,
25985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                      "di.readdwarf3.pTD.enumerator.1" );
2599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
26005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_const_value && cts.szB > 0) {
26015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            atomE.Te.Atom.value      = cts.u.val;
2602f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj            atomE.Te.Atom.valueKnown = True;
2603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2605b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
2606f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      if (atomE.Te.Atom.name == NULL)
2607b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto bad_DIE;
2608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have a plausible parent? */
2609b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (typestack_is_empty(parser)) goto bad_DIE;
26109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
26119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(parser->qparentE[parser->sp].cuOff != D3_INVALID_CUOFF);
2612b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (level != parser->qlevel[parser->sp]+1) goto bad_DIE;
26139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (parser->qparentE[parser->sp].tag != Te_TyEnum) goto bad_DIE;
2614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Record this child in the parent */
26159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(parser->qparentE[parser->sp].Te.TyEnum.atomRs);
26169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(addToXA)( parser->qparentE[parser->sp].Te.TyEnum.atomRs,
26179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                    &atomE );
2618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* And record the child itself */
2619b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      goto acquire_Atom;
2620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
26226a3a28409187ca6813b228afaf2af288c1fcd73dsewardj   /* Treat DW_TAG_class_type as if it was a DW_TAG_structure_type.  I
26236a3a28409187ca6813b228afaf2af288c1fcd73dsewardj      don't know if this is correct, but it at least makes this reader
26246a3a28409187ca6813b228afaf2af288c1fcd73dsewardj      usable for gcc-4.3 produced Dwarf3. */
26256a3a28409187ca6813b228afaf2af288c1fcd73dsewardj   if (dtag == DW_TAG_structure_type || dtag == DW_TAG_class_type
26266a3a28409187ca6813b228afaf2af288c1fcd73dsewardj       || dtag == DW_TAG_union_type) {
2627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_szB = False;
2628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool is_decl  = False;
2629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool is_spec  = False;
2630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Create a new Type to hold the results. */
26319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
26329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = posn;
26339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyStOrUn;
26349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyStOrUn.name = NULL;
26359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyStOrUn.fieldRs
26369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.pTD.struct_type.1",
26379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                       ML_(dinfo_free),
26389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                       sizeof(UWord) );
26399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyStOrUn.complete = True;
26409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyStOrUn.isStruct = dtag == DW_TAG_structure_type
26419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                   || dtag == DW_TAG_class_type;
2642b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2644b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2645b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
26465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
26475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
26489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            typeE.Te.TyStOrUn.name
26495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = ML_(cur_read_strdup)( cts.u.cur,
26505d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       "di.readdwarf3.ptD.struct_type.2" );
2651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
26525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_byte_size && cts.szB >= 0) {
26535d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyStOrUn.szB = cts.u.val;
2654b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_szB = True;
2655b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
26565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_declaration && cts.szB > 0 && cts.u.val > 0) {
2657b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            is_decl = True;
2658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
26595d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_specification && cts.szB > 0 && cts.u.val > 0) {
2660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            is_spec = True;
2661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
2664b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (is_decl && (!is_spec)) {
2665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* It's a DW_AT_declaration.  We require the name but
2666b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            nothing else. */
266700888885d88a5264711c22074cfd3462020cbee6sewardj         /* JRS 2012-06-28: following discussion w/ tromey, if the the
266800888885d88a5264711c22074cfd3462020cbee6sewardj            type doesn't have name, just make one up, and accept it.
266900888885d88a5264711c22074cfd3462020cbee6sewardj            It might be referred to by other DIEs, so ignoring it
267000888885d88a5264711c22074cfd3462020cbee6sewardj            doesn't seem like a safe option. */
26719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (typeE.Te.TyStOrUn.name == NULL)
267200888885d88a5264711c22074cfd3462020cbee6sewardj            typeE.Te.TyStOrUn.name
267300888885d88a5264711c22074cfd3462020cbee6sewardj               = ML_(dinfo_strdup)( "di.readdwarf3.ptD.struct_type.3",
267400888885d88a5264711c22074cfd3462020cbee6sewardj                                    "<anon_struct_type>" );
26759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         typeE.Te.TyStOrUn.complete = False;
2676b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj         /* JRS 2009 Aug 10: <possible kludge>? */
2677b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj         /* Push this tyent on the stack, even though it's incomplete.
2678b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj            It appears that gcc-4.4 on Fedora 11 will sometimes create
2679b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj            DW_TAG_member entries for it, and so we need to have a
2680b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj            plausible parent present in order for that to work.  See
2681b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj            #200029 comments 8 and 9. */
2682b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj         typestack_push( cc, parser, td3, &typeE, level );
2683b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj         /* </possible kludge> */
2684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto acquire_Type;
2685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if ((!is_decl) /* && (!is_spec) */) {
2687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* this is the common, ordinary case */
2688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if ((!have_szB) /* we must know the size */
2689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             /* But the name can be present, or not */)
2690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            goto bad_DIE;
2691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* On't stack! */
26929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         typestack_push( cc, parser, td3, &typeE, level );
2693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto acquire_Type;
2694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      else {
2696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* don't know how to handle any other variants just now */
2697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto bad_DIE;
2698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2699b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_member) {
2702b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Acquire member entries for both DW_TAG_structure_type and
2703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_TAG_union_type.  They differ minorly, in that struct
2704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         members must have a DW_AT_data_member_location expression
2705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         whereas union members must not. */
2706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool parent_is_struct;
27079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)( &fieldE, 0, sizeof(fieldE) );
27089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      fieldE.cuOff = posn;
27099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      fieldE.tag   = Te_Field;
27109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      fieldE.Te.Field.typeR = D3_INVALID_CUOFF;
2711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
27155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
27165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
27179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            fieldE.Te.Field.name
27185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = ML_(cur_read_strdup)( cts.u.cur,
27195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       "di.readdwarf3.ptD.member.1" );
2720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
27215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_type && cts.szB > 0) {
27225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            fieldE.Te.Field.typeR
27235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = cook_die_using_form( cc, (UWord)cts.u.val, form );
2724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
27253c9cf3442185b5891e15450d6e3058aeff6796fetom         /* There are 2 different cases for DW_AT_data_member_location.
27263c9cf3442185b5891e15450d6e3058aeff6796fetom            If it is a constant class attribute, it contains byte offset
27273c9cf3442185b5891e15450d6e3058aeff6796fetom            from the beginning of the containing entity.
27283c9cf3442185b5891e15450d6e3058aeff6796fetom            Otherwise it is a location expression.  */
27295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_data_member_location && cts.szB > 0) {
27303c9cf3442185b5891e15450d6e3058aeff6796fetom            fieldE.Te.Field.nLoc = -1;
27315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            fieldE.Te.Field.pos.offset = cts.u.val;
27325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
27335d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_data_member_location && cts.szB <= 0) {
27345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            fieldE.Te.Field.nLoc = (UWord)(-cts.szB);
27353c9cf3442185b5891e15450d6e3058aeff6796fetom            fieldE.Te.Field.pos.loc
27365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = ML_(cur_read_memdup)( cts.u.cur,
27375d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       (SizeT)fieldE.Te.Field.nLoc,
27385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       "di.readdwarf3.ptD.member.2" );
2739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have a plausible parent? */
2742b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (typestack_is_empty(parser)) goto bad_DIE;
27439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
27449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(parser->qparentE[parser->sp].cuOff != D3_INVALID_CUOFF);
2745b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (level != parser->qlevel[parser->sp]+1) goto bad_DIE;
27469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (parser->qparentE[parser->sp].tag != Te_TyStOrUn) goto bad_DIE;
2747b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane?  If this a member of a
2748b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         struct, we must have a location expression; but if a member
2749b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         of a union that is irrelevant (D3 spec sec 5.6.6).  We ought
2750b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         to reject in the latter case, but some compilers have been
2751b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         observed to emit constant-zero expressions.  So just ignore
2752b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         them. */
2753b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parent_is_struct
27549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         = parser->qparentE[parser->sp].Te.TyStOrUn.isStruct;
27559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (!fieldE.Te.Field.name)
27569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         fieldE.Te.Field.name
27579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = ML_(dinfo_strdup)( "di.readdwarf3.ptD.member.3",
27589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                 "<anon_field>" );
27599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(fieldE.Te.Field.name);
27609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (fieldE.Te.Field.typeR == D3_INVALID_CUOFF)
2761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto bad_DIE;
27623c9cf3442185b5891e15450d6e3058aeff6796fetom      if (fieldE.Te.Field.nLoc) {
276307de5ddba10bfebab8416a8f79c349faa62bbaa1tom         if (!parent_is_struct) {
276407de5ddba10bfebab8416a8f79c349faa62bbaa1tom            /* If this is a union type, pretend we haven't seen the data
276507de5ddba10bfebab8416a8f79c349faa62bbaa1tom               member location expression, as it is by definition
276607de5ddba10bfebab8416a8f79c349faa62bbaa1tom               redundant (it must be zero). */
27673c9cf3442185b5891e15450d6e3058aeff6796fetom            if (fieldE.Te.Field.nLoc > 0)
27683c9cf3442185b5891e15450d6e3058aeff6796fetom               ML_(dinfo_free)(fieldE.Te.Field.pos.loc);
27693c9cf3442185b5891e15450d6e3058aeff6796fetom            fieldE.Te.Field.pos.loc = NULL;
277007de5ddba10bfebab8416a8f79c349faa62bbaa1tom            fieldE.Te.Field.nLoc = 0;
277107de5ddba10bfebab8416a8f79c349faa62bbaa1tom         }
277207de5ddba10bfebab8416a8f79c349faa62bbaa1tom         /* Record this child in the parent */
277307de5ddba10bfebab8416a8f79c349faa62bbaa1tom         fieldE.Te.Field.isStruct = parent_is_struct;
277407de5ddba10bfebab8416a8f79c349faa62bbaa1tom         vg_assert(parser->qparentE[parser->sp].Te.TyStOrUn.fieldRs);
277507de5ddba10bfebab8416a8f79c349faa62bbaa1tom         VG_(addToXA)( parser->qparentE[parser->sp].Te.TyStOrUn.fieldRs,
277607de5ddba10bfebab8416a8f79c349faa62bbaa1tom                       &posn );
277707de5ddba10bfebab8416a8f79c349faa62bbaa1tom         /* And record the child itself */
277807de5ddba10bfebab8416a8f79c349faa62bbaa1tom         goto acquire_Field;
277907de5ddba10bfebab8416a8f79c349faa62bbaa1tom      } else {
278007de5ddba10bfebab8416a8f79c349faa62bbaa1tom         /* Member with no location - this can happen with static
278107de5ddba10bfebab8416a8f79c349faa62bbaa1tom            const members in C++ code which are compile time constants
278207de5ddba10bfebab8416a8f79c349faa62bbaa1tom            that do no exist in the class. They're not of any interest
278307de5ddba10bfebab8416a8f79c349faa62bbaa1tom            to us so we ignore them. */
2784d9df0ea979e3dd5b732b8cced076a105fa45f352philippe         ML_(TyEnt__make_EMPTY)(&fieldE);
2785b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2786b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2787b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_array_type) {
27899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
27909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = posn;
27919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyArray;
27929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyArray.typeR = D3_INVALID_CUOFF;
27939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyArray.boundRs
27949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ptD.array_type.1",
27959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                       ML_(dinfo_free),
27969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                       sizeof(UWord) );
2797b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2798b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2799b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2800b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
28015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
28025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_type && cts.szB > 0) {
28035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyArray.typeR
28045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = cook_die_using_form( cc, (UWord)cts.u.val, form );
2805b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2806b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
28079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (typeE.Te.TyArray.typeR == D3_INVALID_CUOFF)
2808b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto bad_DIE;
2809b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* On't stack! */
28109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typestack_push( cc, parser, td3, &typeE, level );
2811b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      goto acquire_Type;
2812b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
28142acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   /* this is a subrange type defining the bounds of an array. */
28152acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   if (dtag == DW_TAG_subrange_type
28162acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj       && subrange_type_denotes_array_bounds(parser, dtag)) {
2817b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_lower = False;
2818b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_upper = False;
2819b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_count = False;
2820b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Long lower = 0;
2821b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Long upper = 0;
2822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2823b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      switch (parser->language) {
2824b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         case 'C': have_lower = True;  lower = 0; break;
2825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         case 'F': have_lower = True;  lower = 1; break;
2826b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         case '?': have_lower = False; break;
28272acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj         case 'A': have_lower = False; break;
2828b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         default:  vg_assert(0); /* assured us by handling of
2829b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                    DW_TAG_compile_unit in this fn */
2830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
28319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
28329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)( &boundE, 0, sizeof(boundE) );
28339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      boundE.cuOff = D3_INVALID_CUOFF;
28349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      boundE.tag   = Te_Bound;
2835b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2836b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2837b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2838b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
28395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
28405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_lower_bound && cts.szB > 0) {
28415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            lower      = (Long)cts.u.val;
2842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_lower = True;
2843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
28445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_upper_bound && cts.szB > 0) {
28455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            upper      = (Long)cts.u.val;
2846b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_upper = True;
2847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
28485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_count && cts.szB > 0) {
28495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            /*count    = (Long)cts.u.val;*/
2850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_count = True;
2851b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* FIXME: potentially skip the rest if no parent present, since
2854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         it could be the case that this subrange type is free-standing
2855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (not being used to describe the bounds of a containing array
2856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         type) */
2857b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have a plausible parent? */
2858b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (typestack_is_empty(parser)) goto bad_DIE;
28599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
28609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(parser->qparentE[parser->sp].cuOff != D3_INVALID_CUOFF);
2861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (level != parser->qlevel[parser->sp]+1) goto bad_DIE;
28629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (parser->qparentE[parser->sp].tag != Te_TyArray) goto bad_DIE;
2863b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2864b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Figure out if we have a definite range or not */
2865b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (have_lower && have_upper && (!have_count)) {
28669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.knownL = True;
28679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.knownU = True;
28689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.boundL = lower;
28699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.boundU = upper;
287072259920f8cad01708271879caca023969463d16tom      }
2871b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      else if (have_lower && (!have_upper) && (!have_count)) {
28729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.knownL = True;
28739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.knownU = False;
28749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.boundL = lower;
28759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.boundU = 0;
287672259920f8cad01708271879caca023969463d16tom      }
287772259920f8cad01708271879caca023969463d16tom      else if ((!have_lower) && have_upper && (!have_count)) {
287872259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.knownL = False;
287972259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.knownU = True;
288072259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.boundL = 0;
288172259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.boundU = upper;
288272259920f8cad01708271879caca023969463d16tom      }
288372259920f8cad01708271879caca023969463d16tom      else if ((!have_lower) && (!have_upper) && (!have_count)) {
288472259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.knownL = False;
288572259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.knownU = False;
288672259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.boundL = 0;
288772259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.boundU = 0;
2888b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else {
2889b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* FIXME: handle more cases */
2890b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto bad_DIE;
2891b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2892b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2893b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Record this bound in the parent */
28949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      boundE.cuOff = posn;
28959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(parser->qparentE[parser->sp].Te.TyArray.boundRs);
28969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(addToXA)( parser->qparentE[parser->sp].Te.TyArray.boundRs,
2897471d6b3eba2d617279c3954a13e322174a0eec13sewardj                    &boundE.cuOff );
2898b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* And record the child itself */
28999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      goto acquire_Bound;
2900b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2901b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
29022acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   /* typedef or subrange_type other than array bounds. */
29032acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   if (dtag == DW_TAG_typedef
29042acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj       || (dtag == DW_TAG_subrange_type
29052acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj           && !subrange_type_denotes_array_bounds(parser, dtag))) {
29062acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      /* subrange_type other than array bound is only for Ada. */
29072acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      vg_assert (dtag == DW_TAG_typedef || parser->language == 'A');
29082acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      /* We can pick up a new typedef/subrange_type any time. */
29099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
29109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = D3_INVALID_CUOFF;
29119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyTyDef;
29129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyTyDef.name = NULL;
29139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyTyDef.typeR = D3_INVALID_CUOFF;
2914b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2915b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2916b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2917b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
29185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
29195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
29209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            typeE.Te.TyTyDef.name
29215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = ML_(cur_read_strdup)( cts.u.cur,
29225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       "di.readdwarf3.ptD.typedef.1" );
2923b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
29245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_type && cts.szB > 0) {
29255d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyTyDef.typeR
29265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = cook_die_using_form( cc, (UWord)cts.u.val, form );
2927b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2928b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2929b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
2930b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (/* must have a name */
29319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj          typeE.Te.TyTyDef.name == NULL
29322acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj          /* However gcc gnat Ada generates minimal typedef
29332acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj             such as the below => accept no name for Ada.
29342acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj             <6><91cc>: DW_TAG_typedef
29352acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj                DW_AT_abstract_ori: <9066>
29362acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj          */
29372acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj          && parser->language != 'A'
2938b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          /* but the referred-to type can be absent */)
2939b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto bad_DIE;
2940b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      else
2941b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto acquire_Type;
2942b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2943b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2944b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_subroutine_type) {
2945b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* function type? just record that one fact and ask no
2946b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         further questions. */
29479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
29489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = D3_INVALID_CUOFF;
29499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyFn;
2950b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      goto acquire_Type;
2951b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2952b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2953b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_volatile_type || dtag == DW_TAG_const_type) {
2954b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int have_ty = 0;
29559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
29569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = D3_INVALID_CUOFF;
29579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyQual;
29589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyQual.qual
2959b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         = dtag == DW_TAG_volatile_type ? 'V' : 'C';
2960b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* target type defaults to 'void' */
29619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyQual.typeR = D3_FAKEVOID_CUOFF;
2962b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2963b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2964b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2965b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
29665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
29675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_type && cts.szB > 0) {
29685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyQual.typeR
29695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = cook_die_using_form( cc, (UWord)cts.u.val, form );
2970b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_ty++;
2971b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2972b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2973b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* gcc sometimes generates DW_TAG_const/volatile_type without
2974b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT_type and GDB appears to interpret the type as 'const
2975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         void' (resp. 'volatile void').  So just allow it .. */
2976b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (have_ty == 1 || have_ty == 0)
2977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto acquire_Type;
2978b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      else
2979b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto bad_DIE;
2980b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2981b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2982e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart   /*
2983e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart    * Treat DW_TAG_unspecified_type as type void. An example of DW_TAG_unspecified_type:
2984e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart    *
2985e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart    * $ readelf --debug-dump /usr/lib/debug/usr/lib/libstdc++.so.6.0.16.debug
2986e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart    *  <1><10d4>: Abbrev Number: 53 (DW_TAG_unspecified_type)
2987e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart    *     <10d5>   DW_AT_name        : (indirect string, offset: 0xdb7): decltype(nullptr)
2988e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart    */
2989e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart   if (dtag == DW_TAG_unspecified_type) {
2990e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart      VG_(memset)(&typeE, 0, sizeof(typeE));
2991e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart      typeE.cuOff           = D3_INVALID_CUOFF;
2992e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart      typeE.tag             = Te_TyQual;
2993e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart      typeE.Te.TyQual.typeR = D3_FAKEVOID_CUOFF;
2994e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart      goto acquire_Type;
2995e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart   }
2996e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart
2997b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* else ignore this DIE */
2998b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return;
2999b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
3000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  acquire_Type:
3002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (0) VG_(printf)("YYYY Acquire Type\n");
30039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(ML_(TyEnt__is_type)( &typeE ));
30049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(typeE.cuOff == D3_INVALID_CUOFF || typeE.cuOff == posn);
30059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   typeE.cuOff = posn;
30069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(addToXA)( tyents, &typeE );
3007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return;
3008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
3009b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  acquire_Atom:
3011b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (0) VG_(printf)("YYYY Acquire Atom\n");
30129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(atomE.tag == Te_Atom);
30139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(atomE.cuOff == D3_INVALID_CUOFF || atomE.cuOff == posn);
30149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   atomE.cuOff = posn;
30159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(addToXA)( tyents, &atomE );
3016b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return;
3017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
3018b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
30199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj  acquire_Field:
3020b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* For union members, Expr should be absent */
30219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (0) VG_(printf)("YYYY Acquire Field\n");
30229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(fieldE.tag == Te_Field);
30233c9cf3442185b5891e15450d6e3058aeff6796fetom   vg_assert(fieldE.Te.Field.nLoc <= 0 || fieldE.Te.Field.pos.loc != NULL);
30243c9cf3442185b5891e15450d6e3058aeff6796fetom   vg_assert(fieldE.Te.Field.nLoc != 0 || fieldE.Te.Field.pos.loc == NULL);
30259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (fieldE.Te.Field.isStruct) {
30263c9cf3442185b5891e15450d6e3058aeff6796fetom      vg_assert(fieldE.Te.Field.nLoc != 0);
30279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   } else {
30289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(fieldE.Te.Field.nLoc == 0);
30299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
30309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(fieldE.cuOff == D3_INVALID_CUOFF || fieldE.cuOff == posn);
30319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   fieldE.cuOff = posn;
30329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(addToXA)( tyents, &fieldE );
3033b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return;
3034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
3035b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
30369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj  acquire_Bound:
30379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (0) VG_(printf)("YYYY Acquire Bound\n");
30389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(boundE.tag == Te_Bound);
30399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(boundE.cuOff == D3_INVALID_CUOFF || boundE.cuOff == posn);
30409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   boundE.cuOff = posn;
30419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(addToXA)( tyents, &boundE );
3042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return;
3043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
3044b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  bad_DIE:
3046b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   set_position_of_Cursor( c_die,  saved_die_c_offset );
3047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   set_position_of_Cursor( c_abbv, saved_abbv_c_offset );
3048b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(printf)("\nparse_type_DIE: confused by:\n");
3049f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   posn = uncook_die( cc, posn, &debug_types_flag, &alt_flag );
3050d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   VG_(printf)(" <%d><%lx>: %s", level, posn, ML_(pp_DW_TAG)( dtag ) );
3051d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   if (debug_types_flag) {
3052d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      VG_(printf)(" (in .debug_types)");
3053f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   } else if (alt_flag) {
3054f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      VG_(printf)(" (in alternate .debug_info)");
3055d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   }
3056d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   VG_(printf)("\n");
3057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
3058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
3059b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
3060b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (attr == 0 && form == 0) break;
3061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(printf)("     %18s: ", ML_(pp_DW_AT)(attr));
3062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Get the form contents, so as to print them */
30635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      get_Form_contents( &cts, cc, c_die, True, form );
3064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(printf)("\t\n");
3065b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3066b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(printf)("\n");
3067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   cc->barf("parse_type_DIE: confused by the above DIE");
3068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
3069b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3070b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
3073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
30749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/*--- Compression of type DIE information                  ---*/
3075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
3076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
3077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
30789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic UWord chase_cuOff ( Bool* changed,
30799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                           XArray* /* of TyEnt */ ents,
30809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                           TyEntIndexCache* ents_cache,
30819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                           UWord cuOff )
30829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
30839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEnt* ent;
30849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache, cuOff );
3085b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
30869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (!ent) {
30879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(printf)("chase_cuOff: no entry for 0x%05lx\n", cuOff);
30889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      *changed = False;
30899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      return cuOff;
30909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
309159a2d18d0ddfa241850017252b0804d469187d79sewardj
30929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(ent->tag != Te_EMPTY);
30939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (ent->tag != Te_INDIR) {
30949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      *changed = False;
30959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      return cuOff;
30969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   } else {
30979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ent->Te.INDIR.indR < cuOff);
30989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      *changed = True;
30999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      return ent->Te.INDIR.indR;
3100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
31019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj}
3102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
31039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic
31049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid chase_cuOffs_in_XArray ( Bool* changed,
31059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                              XArray* /* of TyEnt */ ents,
31069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                              TyEntIndexCache* ents_cache,
31079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                              /*MOD*/XArray* /* of UWord */ cuOffs )
31089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
31099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Bool b2 = False;
31109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Word i, n = VG_(sizeXA)( cuOffs );
31119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   for (i = 0; i < n; i++) {
31129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      Bool   b = False;
31139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      UWord* p = VG_(indexXA)( cuOffs, i );
31149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      *p = chase_cuOff( &b, ents, ents_cache, *p );
31159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (b)
31169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         b2 = True;
31179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
31189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   *changed = b2;
3119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
31219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic Bool TyEnt__subst_R_fields ( XArray* /* of TyEnt */ ents,
31229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                    TyEntIndexCache* ents_cache,
31239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                    /*MOD*/TyEnt* te )
31249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
31259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Bool b, changed = False;
31269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   switch (te->tag) {
31279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_EMPTY:
31289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
31299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_INDIR:
31309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         te->Te.INDIR.indR
31319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = chase_cuOff( &b, ents, ents_cache, te->Te.INDIR.indR );
31329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
31339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
31349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_UNKNOWN:
31359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
31369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_Atom:
31379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
31389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_Field:
31399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         te->Te.Field.typeR
31409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = chase_cuOff( &b, ents, ents_cache, te->Te.Field.typeR );
31419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
31429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
31439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_Bound:
31449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
31459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyBase:
31469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
31470e947cfedebda6da2e84fb61af431db5cf1275fcbart      case Te_TyPtr:
31480e947cfedebda6da2e84fb61af431db5cf1275fcbart      case Te_TyRef:
31490e947cfedebda6da2e84fb61af431db5cf1275fcbart      case Te_TyPtrMbr:
31500e947cfedebda6da2e84fb61af431db5cf1275fcbart      case Te_TyRvalRef:
31519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         te->Te.TyPorR.typeR
31529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = chase_cuOff( &b, ents, ents_cache, te->Te.TyPorR.typeR );
31539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
31549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
31559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyTyDef:
31569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         te->Te.TyTyDef.typeR
31579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = chase_cuOff( &b, ents, ents_cache, te->Te.TyTyDef.typeR );
31589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
31599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
31609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyStOrUn:
31619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyStOrUn.fieldRs );
31629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
31639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
31649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyEnum:
31659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyEnum.atomRs );
31669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
31679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
31689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyArray:
31699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         te->Te.TyArray.typeR
31709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = chase_cuOff( &b, ents, ents_cache, te->Te.TyArray.typeR );
31719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
31729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyArray.boundRs );
31739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
31749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
31759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyFn:
31769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
31779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyQual:
31789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         te->Te.TyQual.typeR
31799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = chase_cuOff( &b, ents, ents_cache, te->Te.TyQual.typeR );
31809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
31819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
31829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyVoid:
31839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
31849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      default:
31859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ML_(pp_TyEnt)(te);
31869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(0);
31879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
31889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   return changed;
31899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj}
319059a2d18d0ddfa241850017252b0804d469187d79sewardj
31919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Make a pass over 'ents'.  For each tyent, inspect the target of any
31929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   'R' or 'Rs' fields (those which refer to other tyents), and replace
31939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   any which point to INDIR nodes with the target of the indirection
31949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   (which should not itself be an indirection).  In summary, this
31959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   routine shorts out all references to indirection nodes. */
31969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic
31979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjWord dedup_types_substitution_pass ( /*MOD*/XArray* /* of TyEnt */ ents,
31989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                     TyEntIndexCache* ents_cache )
31999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
32009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Word i, n, nChanged = 0;
32019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Bool b;
32029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   n = VG_(sizeXA)( ents );
32039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   for (i = 0; i < n; i++) {
32049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TyEnt* ent = VG_(indexXA)( ents, i );
32059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ent->tag != Te_EMPTY);
32069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* We have to substitute everything, even indirections, so as to
32079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ensure that chains of indirections don't build up. */
32089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      b = TyEnt__subst_R_fields( ents, ents_cache, ent );
32099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (b)
32109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         nChanged++;
32119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
321259a2d18d0ddfa241850017252b0804d469187d79sewardj
32139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   return nChanged;
32149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj}
321559a2d18d0ddfa241850017252b0804d469187d79sewardj
321659a2d18d0ddfa241850017252b0804d469187d79sewardj
32179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Make a pass over 'ents', building a dictionary of TyEnts as we go.
32189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Look up each new tyent in the dictionary in turn.  If it is already
32199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   in the dictionary, replace this tyent with an indirection to the
32209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   existing one, and delete any malloc'd stuff hanging off this one.
32219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   In summary, this routine commons up all tyents that are identical
32229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   as defined by TyEnt__cmp_by_all_except_cuOff. */
32239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic
32249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjWord dedup_types_commoning_pass ( /*MOD*/XArray* /* of TyEnt */ ents )
3225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
32269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Word    n, i, nDeleted;
32279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   WordFM* dict; /* TyEnt* -> void */
32289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEnt*  ent;
32299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   UWord   keyW, valW;
32309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
32319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   dict = VG_(newFM)(
32329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj             ML_(dinfo_zalloc), "di.readdwarf3.dtcp.1",
32339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj             ML_(dinfo_free),
32349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj             (Word(*)(UWord,UWord)) ML_(TyEnt__cmp_by_all_except_cuOff)
32359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj          );
32369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
32379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   nDeleted = 0;
32389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   n = VG_(sizeXA)( ents );
32399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   for (i = 0; i < n; i++) {
32409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      ent = VG_(indexXA)( ents, i );
32419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ent->tag != Te_EMPTY);
32429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
32439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* Ignore indirections, although check that they are
32449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         not forming a cycle. */
32459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (ent->tag == Te_INDIR) {
32469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(ent->Te.INDIR.indR < ent->cuOff);
32479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         continue;
32489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      }
3249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
32509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      keyW = valW = 0;
32519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (VG_(lookupFM)( dict, &keyW, &valW, (UWord)ent )) {
32529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         /* it's already in the dictionary. */
32539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         TyEnt* old = (TyEnt*)keyW;
32549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(valW == 0);
32559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(old != ent);
32569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(old->tag != Te_INDIR);
32579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         /* since we are traversing the array in increasing order of
32589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            cuOff: */
32599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(old->cuOff < ent->cuOff);
32609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         /* So anyway, dump this entry and replace it with an
32619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            indirection to the one in the dictionary.  Note that the
32629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            assertion above guarantees that we cannot create cycles of
32639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            indirections, since we are always creating an indirection
32649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            to a tyent with a cuOff lower than this one. */
32659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ML_(TyEnt__make_EMPTY)( ent );
32669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ent->tag = Te_INDIR;
32679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ent->Te.INDIR.indR = old->cuOff;
32689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         nDeleted++;
32699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      } else {
32709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         /* not in dictionary; add it and keep going. */
32719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         VG_(addToFM)( dict, (UWord)ent, 0 );
32729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      }
32739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
32749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
32759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(deleteFM)( dict, NULL, NULL );
327659a2d18d0ddfa241850017252b0804d469187d79sewardj
32779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   return nDeleted;
32789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj}
3279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
32819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic
32829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid dedup_types ( Bool td3,
32839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                   /*MOD*/XArray* /* of TyEnt */ ents,
32849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                   TyEntIndexCache* ents_cache )
32859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
32869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Word m, n, i, nDel, nSubst, nThresh;
32879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (0) td3 = True;
32889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
32899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   n = VG_(sizeXA)( ents );
32909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
32919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* If a commoning pass and a substitution pass both make fewer than
32929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      this many changes, just stop.  It's pointless to burn up CPU
32939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      time trying to compress the last 1% or so out of the array. */
32949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   nThresh = n / 200;
32959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
32969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* First we must sort .ents by its .cuOff fields, so we
32979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      can index into it. */
32986bd9dc18c043927c1196caba20a327238a179c42florian   VG_(setCmpFnXA)( ents, (XACmpFn_t) ML_(TyEnt__cmp_by_cuOff_only) );
32999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(sortXA)( ents );
33009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
33019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* Now repeatedly do commoning and substitution passes over
33029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      the array, until there are no more changes. */
33039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   do {
33049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      nDel   = dedup_types_commoning_pass ( ents );
33059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      nSubst = dedup_types_substitution_pass ( ents, ents_cache );
33069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(nDel >= 0 && nSubst >= 0);
33079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TRACE_D3("   %ld deletions, %ld substitutions\n", nDel, nSubst);
33089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   } while (nDel > nThresh || nSubst > nThresh);
33099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
33109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* Sanity check: all INDIR nodes should point at a non-INDIR thing.
33119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      In fact this should be true at the end of every loop iteration
33129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      above (a commoning pass followed by a substitution pass), but
33139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      checking it on every iteration is excessively expensive.  Note,
33149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      this loop also computes 'm' for the stats printing below it. */
33159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   m = 0;
33169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   n = VG_(sizeXA)( ents );
331759a2d18d0ddfa241850017252b0804d469187d79sewardj   for (i = 0; i < n; i++) {
33189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TyEnt *ent, *ind;
33199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      ent = VG_(indexXA)( ents, i );
33209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (ent->tag != Te_INDIR) continue;
33219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      m++;
33229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      ind = ML_(TyEnts__index_by_cuOff)( ents, ents_cache,
33239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                         ent->Te.INDIR.indR );
33249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ind);
33259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ind->tag != Te_INDIR);
3326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
33289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TRACE_D3("Overall: %ld before, %ld after\n", n, n-m);
33299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj}
33309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
33319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
33329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/*------------------------------------------------------------*/
33339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/*---                                                      ---*/
33349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/*--- Resolution of references to type DIEs                ---*/
33359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/*---                                                      ---*/
33369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/*------------------------------------------------------------*/
33379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
33389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Make a pass through the (temporary) variables array.  Examine the
33399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   type of each variable, check is it found, and chase any Te_INDIRs.
33409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Postcondition is: each variable has a typeR field that refers to a
33419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   valid type in tyents, or a Te_UNKNOWN, and is certainly guaranteed
33429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   not to refer to a Te_INDIR.  (This is so that we can throw all the
33439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Te_INDIRs away later). */
33449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
33459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj__attribute__((noinline))
33469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic void resolve_variable_types (
33476bd9dc18c043927c1196caba20a327238a179c42florian               void (*barf)( const HChar* ) __attribute__((noreturn)),
33489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               /*R-O*/XArray* /* of TyEnt */ ents,
33499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               /*MOD*/TyEntIndexCache* ents_cache,
33509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               /*MOD*/XArray* /* of TempVar* */ vars
33519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            )
33529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
33539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Word i, n;
335459a2d18d0ddfa241850017252b0804d469187d79sewardj   n = VG_(sizeXA)( vars );
335559a2d18d0ddfa241850017252b0804d469187d79sewardj   for (i = 0; i < n; i++) {
335659a2d18d0ddfa241850017252b0804d469187d79sewardj      TempVar* var = *(TempVar**)VG_(indexXA)( vars, i );
33579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* This is the stated type of the variable.  But it might be
33589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         an indirection, so be careful. */
33599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TyEnt* ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache,
33609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                                var->typeR );
33619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (ent && ent->tag == Te_INDIR) {
33629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache,
33639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                            ent->Te.INDIR.indR );
33649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(ent);
33659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(ent->tag != Te_INDIR);
33669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      }
3367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
33689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* Deal first with "normal" cases */
33699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (ent && ML_(TyEnt__is_type)(ent)) {
33709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         var->typeR = ent->cuOff;
33719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         continue;
33729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      }
33739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
33749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* If there's no ent, it probably we did not manage to read a
33759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         type at the cuOffset which is stated as being this variable's
33769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         type.  Maybe a deficiency in parse_type_DIE.  Complain. */
33779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (ent == NULL) {
33789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         VG_(printf)("\n: Invalid cuOff = 0x%05lx\n", var->typeR );
33799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         barf("resolve_variable_types: "
33809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj              "cuOff does not refer to a known type");
33819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      }
33829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ent);
33839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* If ent has any other tag, something bad happened, along the
33849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         lines of var->typeR not referring to a type at all. */
33859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ent->tag == Te_UNKNOWN);
33869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* Just accept it; the type will be useless, but at least keep
33879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         going. */
33889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      var->typeR = ent->cuOff;
3389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
3394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
3395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Parsing of Compilation Units                         ---*/
3396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
3397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
3398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
33996bd9dc18c043927c1196caba20a327238a179c42florianstatic Int cmp_TempVar_by_dioff ( const void* v1, const void* v2 ) {
34003e7986312a0ffc7646b0552d4c4ea3744a870e73florian   const TempVar* t1 = *(const TempVar *const *)v1;
34013e7986312a0ffc7646b0552d4c4ea3744a870e73florian   const TempVar* t2 = *(const TempVar *const *)v2;
3402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (t1->dioff < t2->dioff) return -1;
3403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (t1->dioff > t2->dioff) return 1;
3404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return 0;
3405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
34079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic void read_DIE (
34089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/WordFM* /* of (XArray* of AddrRange, void) */ rangestree,
34099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/XArray* /* of TyEnt */ tyents,
34109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/XArray* /* of TempVar* */ tempvars,
34119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/XArray* /* of GExpr* */ gexprs,
34129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/D3TypeParser* typarser,
34139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/D3VarParser* varparser,
34149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Cursor* c, Bool td3, CUConst* cc, Int level
34159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj)
3416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
3417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Cursor abbv;
3418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ULong  atag, abbv_code;
3419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UWord  posn;
3420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt   has_children;
3421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UWord  start_die_c_offset, start_abbv_c_offset;
3422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UWord  after_die_c_offset, after_abbv_c_offset;
3423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* --- Deal with this DIE --- */
3425d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   posn      = cook_die( cc, get_position_of_Cursor( c ) );
3426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   abbv_code = get_ULEB128( c );
3427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   set_abbv_Cursor( &abbv, td3, cc, abbv_code );
3428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   atag      = get_ULEB128( &abbv );
3429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3("\n");
3430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3(" <%d><%lx>: Abbrev Number: %llu (%s)\n",
3431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            level, posn, abbv_code, ML_(pp_DW_TAG)( atag ) );
3432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (atag == 0)
3434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("read_DIE: invalid zero tag on DIE");
3435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   has_children = get_UChar( &abbv );
3437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (has_children != DW_children_no && has_children != DW_children_yes)
3438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("read_DIE: invalid has_children value");
3439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* We're set up to look at the fields of this DIE.  Hand it off to
3441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      any parser(s) that want to see it.  Since they will in general
3442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      advance both the DIE and abbrev cursors, remember their current
3443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      settings so that we can then back up and do one final pass over
3444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      the DIE, to print out its contents. */
3445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   start_die_c_offset  = get_position_of_Cursor( c );
3447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   start_abbv_c_offset = get_position_of_Cursor( &abbv );
3448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
34505d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      FormContents cts;
3451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ULong at_name = get_ULEB128( &abbv );
3452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ULong at_form = get_ULEB128( &abbv );
3453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (at_name == 0 && at_form == 0) break;
3454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("     %18s: ", ML_(pp_DW_AT)(at_name));
3455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Get the form contents, but ignore them; the only purpose is
3456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         to print them, if td3 is True */
34575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      get_Form_contents( &cts, cc, c, td3, (DW_FORM)at_form );
3458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("\t");
3459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("\n");
3460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   after_die_c_offset  = get_position_of_Cursor( c );
3463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   after_abbv_c_offset = get_position_of_Cursor( &abbv );
3464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   set_position_of_Cursor( c,     start_die_c_offset );
3466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   set_position_of_Cursor( &abbv, start_abbv_c_offset );
3467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
34689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   parse_type_DIE( tyents,
3469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   typarser,
3470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   (DW_TAG)atag,
3471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   posn,
3472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   level,
3473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   c,     /* DIE cursor */
3474b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   &abbv, /* abbrev cursor */
3475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   cc,
3476b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   td3 );
3477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   set_position_of_Cursor( c,     start_die_c_offset );
3479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   set_position_of_Cursor( &abbv, start_abbv_c_offset );
3480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
34819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   parse_var_DIE( rangestree,
34829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                  tempvars,
3483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  gexprs,
3484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  varparser,
3485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  (DW_TAG)atag,
3486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  posn,
3487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  level,
3488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  c,     /* DIE cursor */
3489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  &abbv, /* abbrev cursor */
3490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  cc,
3491b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  td3 );
3492b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3493b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   set_position_of_Cursor( c,     after_die_c_offset );
3494b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   set_position_of_Cursor( &abbv, after_abbv_c_offset );
3495b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3496b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* --- Now recurse into its children, if any --- */
3497b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (has_children == DW_children_yes) {
3498b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (0) TRACE_D3("BEGIN children of level %d\n", level);
3499b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
3500b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         atag = peek_ULEB128( c );
3501b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (atag == 0) break;
35029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         read_DIE( rangestree, tyents, tempvars, gexprs,
35039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                   typarser, varparser,
3504b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   c, td3, cc, level+1 );
3505b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3506b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Now we need to eat the terminating zero */
3507b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      atag = get_ULEB128( c );
3508b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(atag == 0);
3509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (0) TRACE_D3("END children of level %d\n", level);
3510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3513b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3514b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3515b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
3516b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid new_dwarf3_reader_wrk (
3517b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct _DebugInfo* di,
35186bd9dc18c043927c1196caba20a327238a179c42florian   __attribute__((noreturn)) void (*barf)( const HChar* ),
35195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_info,      DiSlice escn_debug_types,
35205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_abbv,      DiSlice escn_debug_line,
35215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_str,       DiSlice escn_debug_ranges,
35225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_loc,       DiSlice escn_debug_info_alt,
35235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_abbv_alt,  DiSlice escn_debug_line_alt,
35245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_str_alt
3525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj)
3526b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
35279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   XArray* /* of TyEnt */     tyents;
35289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   XArray* /* of TyEnt */     tyents_to_keep;
35299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   XArray* /* of GExpr* */    gexprs;
35309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   XArray* /* of TempVar* */  tempvars;
35319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   WordFM* /* of (XArray* of AddrRange, void) */ rangestree;
35329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEntIndexCache* tyents_cache = NULL;
35339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEntIndexCache* tyents_to_keep_cache = NULL;
353459a2d18d0ddfa241850017252b0804d469187d79sewardj   TempVar *varp, *varp2;
353559a2d18d0ddfa241850017252b0804d469187d79sewardj   GExpr* gexpr;
3536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Cursor abbv; /* for showing .debug_abbrev */
3537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Cursor info; /* primary cursor for parsing .debug_info */
3538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Cursor ranges; /* for showing .debug_ranges */
3539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   D3TypeParser typarser;
3540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   D3VarParser varparser;
3541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Addr  dr_base;
3542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UWord dr_offset;
354359a2d18d0ddfa241850017252b0804d469187d79sewardj   Word  i, j, n;
3544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool td3 = di->trace_symtab;
3545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   XArray* /* of TempVar* */ dioff_lookup_tab;
3546d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   Int pass;
3547d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   VgHashTable signature_types;
3548b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#if 0
3549b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* This doesn't work properly because it assumes all entries are
3550b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      packed end to end, with no holes.  But that doesn't always
3551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      appear to be the case, so it loses sync.  And the D3 spec
3552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      doesn't appear to require a no-hole situation either. */
3553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Display .debug_loc */
3554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Addr  dl_base;
3555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UWord dl_offset;
3556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Cursor loc; /* for showing .debug_loc */
3557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n");
3558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n------ The contents of .debug_loc ------\n");
3559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("    Offset   Begin    End      Expression\n");
3560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   init_Cursor( &loc, debug_loc_img,
3561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                debug_loc_sz, 0, barf,
3562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                "Overrun whilst reading .debug_loc section(1)" );
3563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   dl_base = 0;
3564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   dl_offset = 0;
3565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
3566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord  w1, w2;
3567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord  len;
3568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (is_at_end_Cursor( &loc ))
3569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
3570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Read a (host-)word pair.  This is something of a hack since
3572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         the word size to read is really dictated by the ELF file;
3573b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         however, we assume we're reading a file with the same
3574b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         word-sizeness as the host.  Reasonably enough. */
3575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      w1 = get_UWord( &loc );
3576b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      w2 = get_UWord( &loc );
3577b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3578b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 == 0 && w2 == 0) {
3579b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* end of list.  reset 'base' */
3580b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("    %08lx <End of list>\n", dl_offset);
3581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         dl_base = 0;
3582b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         dl_offset = get_position_of_Cursor( &loc );
3583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         continue;
3584b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3585b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3586b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 == -1UL) {
3587b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* new value for 'base' */
3588b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("    %08lx %16lx %08lx (base address)\n",
3589b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  dl_offset, w1, w2);
3590b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         dl_base = w2;
3591b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         continue;
3592b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3594b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* else a location expression follows */
3595b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("    %08lx %08lx %08lx ",
3596b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               dl_offset, w1 + dl_base, w2 + dl_base);
3597b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      len = (UWord)get_UShort( &loc );
3598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (len > 0) {
3599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UChar byte = get_UChar( &loc );
3600b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("%02x", (UInt)byte);
3601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         len--;
3602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_SYMTAB("\n");
3604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3605b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
3606b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3607b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Display .debug_ranges */
3608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n");
3609b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n------ The contents of .debug_ranges ------\n");
3610b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("    Offset   Begin    End\n");
36115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (ML_(sli_is_valid)(escn_debug_ranges)) {
36125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      init_Cursor( &ranges, escn_debug_ranges, 0, barf,
36135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                   "Overrun whilst reading .debug_ranges section(1)" );
36145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      dr_base = 0;
36155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      dr_offset = 0;
36165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      while (True) {
36175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UWord  w1, w2;
3618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
36195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (is_at_end_Cursor( &ranges ))
36205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            break;
3621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
36225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         /* Read a (host-)word pair.  This is something of a hack since
36235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            the word size to read is really dictated by the ELF file;
36245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            however, we assume we're reading a file with the same
36255d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            word-sizeness as the host.  Reasonably enough. */
36265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         w1 = get_UWord( &ranges );
36275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         w2 = get_UWord( &ranges );
36285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
36295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (w1 == 0 && w2 == 0) {
36305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            /* end of list.  reset 'base' */
36315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            TRACE_D3("    %08lx <End of list>\n", dr_offset);
36325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            dr_base = 0;
36335d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            dr_offset = get_position_of_Cursor( &ranges );
36345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            continue;
36355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
3636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
36375d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (w1 == -1UL) {
36385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            /* new value for 'base' */
36395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            TRACE_D3("    %08lx %16lx %08lx (base address)\n",
36405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                     dr_offset, w1, w2);
36415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            dr_base = w2;
36425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            continue;
36435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
3644b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
36455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         /* else a range [w1+base, w2+base) is denoted */
36465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("    %08lx %08lx %08lx\n",
36475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  dr_offset, w1 + dr_base, w2 + dr_base);
3648b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Display .debug_abbrev */
3652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n");
3653b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n------ The contents of .debug_abbrev ------\n");
36545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (ML_(sli_is_valid)(escn_debug_abbv)) {
36555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      init_Cursor( &abbv, escn_debug_abbv, 0, barf,
36565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                   "Overrun whilst reading .debug_abbrev section" );
3657b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
36585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (is_at_end_Cursor( &abbv ))
36595d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            break;
36605d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         /* Read one abbreviation table */
36615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("  Number TAG\n");
3662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while (True) {
36635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ULong atag;
36645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            UInt  has_children;
36655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ULong acode = get_ULEB128( &abbv );
36665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            if (acode == 0) break; /* end of the table */
36675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            atag = get_ULEB128( &abbv );
36685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            has_children = get_UChar( &abbv );
36695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            TRACE_D3("   %llu      %s    [%s]\n",
36705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                     acode, ML_(pp_DW_TAG)(atag),
36715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                            ML_(pp_DW_children)(has_children));
36725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            while (True) {
36735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               ULong at_name = get_ULEB128( &abbv );
36745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               ULong at_form = get_ULEB128( &abbv );
36755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               if (at_name == 0 && at_form == 0) break;
36765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               TRACE_D3("    %18s %s\n",
36775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                        ML_(pp_DW_AT)(at_name), ML_(pp_DW_FORM)(at_form));
36785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            }
3679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n");
3683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* We'll park the harvested type information in here.  Also create
3685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      a fake "void" entry with offset D3_FAKEVOID_CUOFF, so we always
3686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      have at least one type entry to refer to.  D3_FAKEVOID_CUOFF is
3687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      huge and presumably will not occur in any valid DWARF3 file --
3688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      it would need to have a .debug_info section 4GB long for that to
3689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      happen.  These type entries end up in the DebugInfo. */
36909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   tyents = VG_(newXA)( ML_(dinfo_zalloc),
36919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                        "di.readdwarf3.ndrw.1 (TyEnt temp array)",
36929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                        ML_(dinfo_free), sizeof(TyEnt) );
36939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   { TyEnt tyent;
36949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj     VG_(memset)(&tyent, 0, sizeof(tyent));
36959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj     tyent.tag   = Te_TyVoid;
36969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj     tyent.cuOff = D3_FAKEVOID_CUOFF;
36979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj     tyent.Te.TyVoid.isFake = True;
36989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj     VG_(addToXA)( tyents, &tyent );
36999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
37009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   { TyEnt tyent;
37019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj     VG_(memset)(&tyent, 0, sizeof(tyent));
37029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj     tyent.tag   = Te_UNKNOWN;
37039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj     tyent.cuOff = D3_INVALID_CUOFF;
37049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj     VG_(addToXA)( tyents, &tyent );
37059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
37069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
37079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* This is a tree used to unique-ify the range lists that are
37089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      manufactured by parse_var_DIE.  References to the keys in the
37099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      tree wind up in .rngMany fields in TempVars.  We'll need to
37109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      delete this tree, and the XArrays attached to it, at the end of
37119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      this function. */
37129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   rangestree = VG_(newFM)( ML_(dinfo_zalloc),
37139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                            "di.readdwarf3.ndrw.2 (rangestree)",
37149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                            ML_(dinfo_free),
37159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                            (Word(*)(UWord,UWord))cmp__XArrays_of_AddrRange );
3716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* List of variables we're accumulating.  These don't end up in the
3718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      DebugInfo; instead their contents are handed to ML_(addVar) and
3719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      the list elements are then deleted. */
37209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   tempvars = VG_(newXA)( ML_(dinfo_zalloc),
37219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                          "di.readdwarf3.ndrw.3 (TempVar*s array)",
37229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                          ML_(dinfo_free),
372359a2d18d0ddfa241850017252b0804d469187d79sewardj                          sizeof(TempVar*) );
3724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* List of GExprs we're accumulating.  These wind up in the
3726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      DebugInfo. */
37279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   gexprs = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.4",
37289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                        ML_(dinfo_free), sizeof(GExpr*) );
3729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* We need a D3TypeParser to keep track of partially constructed
3731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      types.  It'll be discarded as soon as we've completed the CU,
37329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      since the resulting information is tipped in to 'tyents' as it
37339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      is generated. */
3734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(memset)( &typarser, 0, sizeof(typarser) );
3735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   typarser.sp = -1;
3736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   typarser.language = '?';
37379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   for (i = 0; i < N_D3_TYPE_STACK; i++) {
37389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typarser.qparentE[i].tag   = Te_EMPTY;
37399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typarser.qparentE[i].cuOff = D3_INVALID_CUOFF;
37409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
3741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3742b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(memset)( &varparser, 0, sizeof(varparser) );
3743b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   varparser.sp = -1;
3744b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3745d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   signature_types = VG_(HT_construct) ("signature_types");
3746d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3747d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   /* Do an initial pass to scan the .debug_types section, if any, and
3748d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      fill in the signatured types hash table.  This lets us handle
3749d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      mapping from a type signature to a (cooked) DIE offset directly
3750d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      in get_Form_contents.  */
37515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (ML_(sli_is_valid)(escn_debug_types)) {
37525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      init_Cursor( &info, escn_debug_types, 0, barf,
3753d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                   "Overrun whilst reading .debug_types section" );
37545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      TRACE_D3("\n------ Collecting signatures from "
37555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               ".debug_types section ------\n");
3756b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3757d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      while (True) {
3758d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         UWord   cu_start_offset, cu_offset_now;
3759d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         CUConst cc;
3760d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3761d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cu_start_offset = get_position_of_Cursor( &info );
3762d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         TRACE_D3("\n");
3763d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         TRACE_D3("  Compilation Unit @ offset 0x%lx:\n", cu_start_offset);
3764d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* parse_CU_header initialises the CU's set_abbv_Cursor cache
3765d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            (saC_cache) */
37665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         parse_CU_Header( &cc, td3, &info, escn_debug_abbv, True, False );
3767d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3768d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* Needed by cook_die.  */
37695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.types_cuOff_bias = escn_debug_info.szB;
3770d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3771d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         record_signatured_type( signature_types, cc.type_signature,
3772d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                                 cook_die( &cc, cc.type_offset ));
3773d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3774d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* Until proven otherwise we assume we don't need the icc9
3775d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            workaround in this case; see the DIE-reading loop below
3776d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            for details.  */
3777d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cu_offset_now = (cu_start_offset + cc.unit_length
3778d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                          + (cc.is_dw64 ? 12 : 4));
3779d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
37805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (cu_offset_now >= escn_debug_types.szB)
3781d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            break;
3782d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3783d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         set_position_of_Cursor ( &info, cu_offset_now );
3784b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3785d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   }
3786d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3787f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   /* Perform three DIE-reading passes.  The first pass reads DIEs from
3788f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      alternate .debug_info (if any), the second pass reads DIEs from
3789f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      .debug_info, and the third pass reads DIEs from .debug_types.
3790d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      Moving the body of this loop into a separate function would
3791d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      require a large number of arguments to be passed in, so it is
3792d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      kept inline instead.  */
3793f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   for (pass = 0; pass < 3; ++pass) {
37945d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      ULong section_size;
3795d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3796d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      if (pass == 0) {
37975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (!ML_(sli_is_valid)(escn_debug_info_alt))
3798f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj	    continue;
3799f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         /* Now loop over the Compilation Units listed in the alternate
3800f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            .debug_info section (see D3SPEC sec 7.5) paras 1 and 2.
3801f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            Each compilation unit contains a Compilation Unit Header
3802f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            followed by precisely one DW_TAG_compile_unit or
3803f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            DW_TAG_partial_unit DIE. */
38045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         init_Cursor( &info, escn_debug_info_alt, 0, barf,
3805f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                      "Overrun whilst reading alternate .debug_info section" );
38065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         section_size = escn_debug_info_alt.szB;
3807f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj
3808f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         TRACE_D3("\n------ Parsing alternate .debug_info section ------\n");
3809f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      } else if (pass == 1) {
3810d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* Now loop over the Compilation Units listed in the .debug_info
3811d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            section (see D3SPEC sec 7.5) paras 1 and 2.  Each compilation
3812d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            unit contains a Compilation Unit Header followed by precisely
3813d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            one DW_TAG_compile_unit or DW_TAG_partial_unit DIE. */
38145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         init_Cursor( &info, escn_debug_info, 0, barf,
3815d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                      "Overrun whilst reading .debug_info section" );
38165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         section_size = escn_debug_info.szB;
3817d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3818d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         TRACE_D3("\n------ Parsing .debug_info section ------\n");
3819d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      } else {
38205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (!ML_(sli_is_valid)(escn_debug_types))
3821d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            continue;
38225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         init_Cursor( &info, escn_debug_types, 0, barf,
3823d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                      "Overrun whilst reading .debug_types section" );
38245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         section_size = escn_debug_types.szB;
3825d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3826d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         TRACE_D3("\n------ Parsing .debug_types section ------\n");
3827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3828b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3829d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      while (True) {
38305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong   cu_start_offset, cu_offset_now;
3831d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         CUConst cc;
3832d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* It may be that the stated size of this CU is larger than the
3833d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            amount of stuff actually in it.  icc9 seems to generate CUs
3834d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            thusly.  We use these variables to figure out if this is
3835d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            indeed the case, and if so how many bytes we need to skip to
3836d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            get to the start of the next CU.  Not skipping those bytes
3837d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            causes us to misidentify the start of the next CU, and it all
3838d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            goes badly wrong after that (not surprisingly). */
3839d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         UWord cu_size_including_IniLen, cu_amount_used;
3840d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3841d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* It seems icc9 finishes the DIE info before debug_info_sz
3842d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            bytes have been used up.  So be flexible, and declare the
3843d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            sequence complete if there is not enough remaining bytes to
3844d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            hold even the smallest conceivable CU header.  (11 bytes I
3845d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            reckon). */
3846d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* JRS 23Jan09: I suspect this is no longer necessary now that
3847d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            the code below contains a 'while (cu_amount_used <
3848d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            cu_size_including_IniLen ...'  style loop, which skips over
3849d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            any leftover bytes at the end of a CU in the case where the
3850d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            CU's stated size is larger than its actual size (as
3851d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            determined by reading all its DIEs).  However, for prudence,
3852d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            I'll leave the following test in place.  I can't see that a
3853d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            CU header can be smaller than 11 bytes, so I don't think
3854d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            there's any harm possible through the test -- it just adds
3855d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            robustness. */
3856d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         Word avail = get_remaining_length_Cursor( &info );
3857d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         if (avail < 11) {
3858d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            if (avail > 0)
3859d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj               TRACE_D3("new_dwarf3_reader_wrk: warning: "
3860d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                        "%ld unused bytes after end of DIEs\n", avail);
3861d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            break;
3862d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         }
3863d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3864d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* Check the varparser's stack is in a sane state. */
3865d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         vg_assert(varparser.sp == -1);
3866d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         for (i = 0; i < N_D3_VAR_STACK; i++) {
3867d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            vg_assert(varparser.ranges[i] == NULL);
3868d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            vg_assert(varparser.level[i] == 0);
3869d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         }
3870d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         for (i = 0; i < N_D3_TYPE_STACK; i++) {
3871d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            vg_assert(typarser.qparentE[i].cuOff == D3_INVALID_CUOFF);
3872d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            vg_assert(typarser.qparentE[i].tag   == Te_EMPTY);
3873d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            vg_assert(typarser.qlevel[i] == 0);
3874d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         }
3875d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3876d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cu_start_offset = get_position_of_Cursor( &info );
3877d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         TRACE_D3("\n");
38785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("  Compilation Unit @ offset 0x%llx:\n", cu_start_offset);
3879d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* parse_CU_header initialises the CU's set_abbv_Cursor cache
3880d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            (saC_cache) */
38815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (pass == 0) {
38825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            parse_CU_Header( &cc, td3, &info, escn_debug_abbv_alt,
3883f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                             False, True );
38845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         } else {
38855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            parse_CU_Header( &cc, td3, &info, escn_debug_abbv,
3886f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                             pass == 2, False );
38875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
38885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_str      = pass == 0 ? escn_debug_str_alt
38895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                            : escn_debug_str;
38905d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_ranges   = escn_debug_ranges;
38915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_loc      = escn_debug_loc;
38925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_line     = pass == 0 ? escn_debug_line_alt
38935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                            : escn_debug_line;
38945d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_info     = pass == 0 ? escn_debug_info_alt
38955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                            : escn_debug_info;
38965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_types    = escn_debug_types;
38975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_info_alt = escn_debug_info_alt;
38985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_str_alt  = escn_debug_str_alt;
38995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.types_cuOff_bias    = escn_debug_info.szB;
39005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.alt_cuOff_bias      = escn_debug_info.szB + escn_debug_types.szB;
39015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.cu_start_offset     = cu_start_offset;
3902d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cc.di = di;
3903d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* The CU's svma can be deduced by looking at the AT_low_pc
3904d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            value in the top level TAG_compile_unit, which is the topmost
3905d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            DIE.  We'll leave it for the 'varparser' to acquire that info
3906d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            and fill it in -- since it is the only party to want to know
3907d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            it. */
3908d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cc.cu_svma_known = False;
3909d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cc.cu_svma       = 0;
3910d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3911d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cc.signature_types = signature_types;
3912d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3913d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* Create a fake outermost-level range covering the entire
3914d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            address range.  So we always have *something* to catch all
3915d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            variable declarations. */
3916d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         varstack_push( &cc, &varparser, td3,
3917d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                        unitary_range_list(0UL, ~0UL),
3918d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                        -1, False/*isFunc*/, NULL/*fbGX*/ );
3919d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3920d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* And set up the file name table.  When we come across the top
3921d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            level DIE for this CU (which is what the next call to
3922d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            read_DIE should process) we will copy all the file names out
3923d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            of the .debug_line img area and use this table to look up the
3924d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            copies when we later see filename numbers in DW_TAG_variables
3925d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            etc. */
3926d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         vg_assert(!varparser.filenameTable );
3927d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         varparser.filenameTable
3928d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.5",
3929d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                          ML_(dinfo_free),
3930d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                          sizeof(UChar*) );
3931d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         vg_assert(varparser.filenameTable);
3932d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3933d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* Now read the one-and-only top-level DIE for this CU. */
3934d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         vg_assert(varparser.sp == 0);
3935d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         read_DIE( rangestree,
3936d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                   tyents, tempvars, gexprs,
3937d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                   &typarser, &varparser,
3938d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                   &info, td3, &cc, 0 );
3939d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3940055b0f85aaa42477a803d445885c389561d3d3c8sewardj         cu_offset_now = get_position_of_Cursor( &info );
3941055b0f85aaa42477a803d445885c389561d3d3c8sewardj
39425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (0) VG_(printf)("Travelled: %llu  size %llu\n",
3943d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                            cu_offset_now - cc.cu_start_offset,
3944d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                            cc.unit_length + (cc.is_dw64 ? 12 : 4));
39454bad5933e7b59ab9c756fb71da0f7fea7c4e61f0philippe
3946d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* How big the CU claims it is .. */
3947d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cu_size_including_IniLen = cc.unit_length + (cc.is_dw64 ? 12 : 4);
3948d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* .. vs how big we have found it to be */
3949d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cu_amount_used = cu_offset_now - cc.cu_start_offset;
3950b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
39515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (1) TRACE_D3("offset now %lld, d-i-size %lld\n",
3952d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                         cu_offset_now, section_size);
3953d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         if (cu_offset_now > section_size)
3954d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            barf("toplevel DIEs beyond end of CU");
3955d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3956d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* If the CU is bigger than it claims to be, we've got a serious
3957d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            problem. */
3958d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         if (cu_amount_used > cu_size_including_IniLen)
3959d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            barf("CU's actual size appears to be larger than it claims it is");
3960d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3961d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* If the CU is smaller than it claims to be, we need to skip some
3962d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            bytes.  Loop updates cu_offset_new and cu_amount_used. */
3963d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         while (cu_amount_used < cu_size_including_IniLen
3964d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                && get_remaining_length_Cursor( &info ) > 0) {
3965d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            if (0) VG_(printf)("SKIP\n");
3966d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            (void)get_UChar( &info );
3967d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            cu_offset_now = get_position_of_Cursor( &info );
3968d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            cu_amount_used = cu_offset_now - cc.cu_start_offset;
3969d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         }
3970b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3971d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* Preen to level -2.  DIEs have level >= 0 so -2 cannot occur
3972d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            anywhere else at all.  Our fake the-entire-address-space
3973d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            range is at level -1, so preening to -2 should completely
3974d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            empty the stack out. */
3975d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         TRACE_D3("\n");
3976d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         varstack_preen( &varparser, td3, -2 );
3977d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* Similarly, empty the type stack out. */
3978d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         typestack_preen( &typarser, td3, -2 );
3979d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3980d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         TRACE_D3("set_abbv_Cursor cache: %lu queries, %lu misses\n",
3981d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                  cc.saC_cache_queries, cc.saC_cache_misses);
3982d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3983d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         vg_assert(varparser.filenameTable );
3984d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         VG_(deleteXA)( varparser.filenameTable );
3985d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         varparser.filenameTable = NULL;
3986d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3987d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         if (cu_offset_now == section_size)
3988d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            break;
3989d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* else keep going */
3990d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      }
3991b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3992b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
399359a2d18d0ddfa241850017252b0804d469187d79sewardj   /* From here on we're post-processing the stuff we got
399459a2d18d0ddfa241850017252b0804d469187d79sewardj      out of the .debug_info section. */
399559a2d18d0ddfa241850017252b0804d469187d79sewardj   if (td3) {
399659a2d18d0ddfa241850017252b0804d469187d79sewardj      TRACE_D3("\n");
39979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      ML_(pp_TyEnts)(tyents, "Initial type entity (TyEnt) array");
3998b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("\n");
39999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TRACE_D3("------ Compressing type entries ------\n");
4000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
40029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   tyents_cache = ML_(dinfo_zalloc)( "di.readdwarf3.ndrw.6",
40039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                     sizeof(TyEntIndexCache) );
40049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   ML_(TyEntIndexCache__invalidate)( tyents_cache );
40059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   dedup_types( td3, tyents, tyents_cache );
40069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (td3) {
40079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TRACE_D3("\n");
40089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      ML_(pp_TyEnts)(tyents, "After type entity (TyEnt) compression");
40099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
40109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
40119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TRACE_D3("\n");
40129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TRACE_D3("------ Resolving the types of variables ------\n" );
40139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   resolve_variable_types( barf, tyents, tyents_cache, tempvars );
40149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
40159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* Copy all the non-INDIR tyents into a new table.  For large
40169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      .so's, about 90% of the tyents will by now have been resolved to
40179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      INDIRs, and we no longer need them, and so don't need to store
40189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      them. */
40199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   tyents_to_keep
40209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      = VG_(newXA)( ML_(dinfo_zalloc),
40219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                    "di.readdwarf3.ndrw.7 (TyEnt to-keep array)",
40229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                    ML_(dinfo_free), sizeof(TyEnt) );
40239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   n = VG_(sizeXA)( tyents );
40249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   for (i = 0; i < n; i++) {
40259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TyEnt* ent = VG_(indexXA)( tyents, i );
40269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (ent->tag != Te_INDIR)
40279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         VG_(addToXA)( tyents_to_keep, ent );
40289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
40299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
40309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(deleteXA)( tyents );
40319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   tyents = NULL;
40329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   ML_(dinfo_free)( tyents_cache );
40339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   tyents_cache = NULL;
40349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
40359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* Sort tyents_to_keep so we can lookup in it.  A complete (if
40369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      minor) waste of time, since tyents itself is sorted, but
40379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      necessary since VG_(lookupXA) refuses to cooperate if we
40389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      don't. */
40396bd9dc18c043927c1196caba20a327238a179c42florian   VG_(setCmpFnXA)( tyents_to_keep, (XACmpFn_t) ML_(TyEnt__cmp_by_cuOff_only) );
40409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(sortXA)( tyents_to_keep );
40419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
40429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* Enable cacheing on tyents_to_keep */
40439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   tyents_to_keep_cache
40449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      = ML_(dinfo_zalloc)( "di.readdwarf3.ndrw.8",
40459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                           sizeof(TyEntIndexCache) );
40469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   ML_(TyEntIndexCache__invalidate)( tyents_to_keep_cache );
40479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
40489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* And record the tyents in the DebugInfo.  We do this before
40499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      starting to hand variables to ML_(addVar), since if ML_(addVar)
40509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      wants to do debug printing (of the types of said vars) then it
40519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      will need the tyents.*/
40529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(!di->admin_tyents);
40539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   di->admin_tyents = tyents_to_keep;
40549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
4055402c9eed11b9b60c6e134d05db938e395466cf99tom   /* Bias all the location expressions. */
40569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TRACE_D3("\n");
40579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TRACE_D3("------ Biasing the location expressions ------\n" );
405868a2ebd9384661a85a4674fe8310c595ad494305sewardj
405959a2d18d0ddfa241850017252b0804d469187d79sewardj   n = VG_(sizeXA)( gexprs );
406059a2d18d0ddfa241850017252b0804d469187d79sewardj   for (i = 0; i < n; i++) {
406159a2d18d0ddfa241850017252b0804d469187d79sewardj      gexpr = *(GExpr**)VG_(indexXA)( gexprs, i );
4062402c9eed11b9b60c6e134d05db938e395466cf99tom      bias_GX( gexpr, di );
4063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4065b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3("\n");
4066b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3("------ Acquired the following variables: ------\n\n");
4067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Park (pointers to) all the vars in an XArray, so we can look up
4069b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      abstract origins quickly.  The array is sorted (hence, looked-up
407059a2d18d0ddfa241850017252b0804d469187d79sewardj      by) the .dioff fields.  Since the .dioffs should be in strictly
4071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ascending order, there is no need to sort the array after
4072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      construction.  The ascendingness is however asserted for. */
4073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   dioff_lookup_tab
40749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.9",
40759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                    ML_(dinfo_free),
4076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    sizeof(TempVar*) );
4077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(dioff_lookup_tab);
407859a2d18d0ddfa241850017252b0804d469187d79sewardj
407959a2d18d0ddfa241850017252b0804d469187d79sewardj   n = VG_(sizeXA)( tempvars );
40805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   Word first_primary_var = 0;
4081f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   for (first_primary_var = 0;
40825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj        escn_debug_info_alt.szB/*really?*/ && first_primary_var < n;
4083f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj        first_primary_var++) {
4084f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      varp = *(TempVar**)VG_(indexXA)( tempvars, first_primary_var );
40855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      if (varp->dioff < escn_debug_info.szB + escn_debug_types.szB)
4086f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         break;
4087f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   }
408859a2d18d0ddfa241850017252b0804d469187d79sewardj   for (i = 0; i < n; i++) {
4089f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      varp = *(TempVar**)VG_(indexXA)( tempvars, (i + first_primary_var) % n );
4090f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      if (i > first_primary_var) {
4091f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         varp2 = *(TempVar**)VG_(indexXA)( tempvars,
4092f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                                           (i + first_primary_var - 1) % n );
409359a2d18d0ddfa241850017252b0804d469187d79sewardj         /* why should this hold?  Only, I think, because we've
409459a2d18d0ddfa241850017252b0804d469187d79sewardj            constructed the array by reading .debug_info sequentially,
409559a2d18d0ddfa241850017252b0804d469187d79sewardj            and so the array .dioff fields should reflect that, and be
409659a2d18d0ddfa241850017252b0804d469187d79sewardj            strictly ascending. */
4097b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vg_assert(varp2->dioff < varp->dioff);
409859a2d18d0ddfa241850017252b0804d469187d79sewardj      }
4099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(addToXA)( dioff_lookup_tab, &varp );
4100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(setCmpFnXA)( dioff_lookup_tab, cmp_TempVar_by_dioff );
4102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(sortXA)( dioff_lookup_tab ); /* POINTLESS; FIXME: rm */
4103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4104b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Now visit each var.  Collect up as much info as possible for
4105b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      each var and hand it to ML_(addVar). */
410659a2d18d0ddfa241850017252b0804d469187d79sewardj   n = VG_(sizeXA)( tempvars );
410759a2d18d0ddfa241850017252b0804d469187d79sewardj   for (j = 0; j < n; j++) {
41089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TyEnt* ent;
410959a2d18d0ddfa241850017252b0804d469187d79sewardj      varp = *(TempVar**)VG_(indexXA)( tempvars, j );
4110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Possibly show .. */
4112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (td3) {
4113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(printf)("<%lx> addVar: level %d: %s :: ",
4114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     varp->dioff,
4115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     varp->level,
41161636d33c13958b9c0e7d3059cdd5005746418eb2florian                     varp->name ? varp->name : "<anon_var>" );
4117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (varp->typeR) {
41189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            ML_(pp_TyEnt_C_ishly)( tyents_to_keep, varp->typeR );
4119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         } else {
4120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            VG_(printf)("NULL");
4121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
4122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(printf)("\n  Loc=");
4123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (varp->gexpr) {
4124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ML_(pp_GX)(varp->gexpr);
4125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         } else {
4126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            VG_(printf)("NULL");
4127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
4128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(printf)("\n");
4129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (varp->fbGX) {
4130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            VG_(printf)("  FrB=");
4131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ML_(pp_GX)( varp->fbGX );
4132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            VG_(printf)("\n");
4133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         } else {
4134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            VG_(printf)("  FrB=none\n");
4135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
4136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(printf)("  declared at: %s:%d\n",
41371636d33c13958b9c0e7d3059cdd5005746418eb2florian                     varp->fName ? varp->fName : "NULL",
4138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     varp->fLine );
4139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (varp->absOri != (UWord)D3_INVALID_CUOFF)
4140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            VG_(printf)("  abstract origin: <%lx>\n", varp->absOri);
4141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Skip variables which have no location.  These must be
4144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         abstract instances; they are useless as-is since with no
4145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         location they have no specified memory location.  They will
4146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         presumably be referred to via the absOri fields of other
4147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         variables. */
4148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (!varp->gexpr) {
4149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("  SKIP (no location)\n\n");
4150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         continue;
4151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* So it has a location, at least.  If it refers to some other
4154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         entry through its absOri field, pull in further info through
4155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         that. */
4156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (varp->absOri != (UWord)D3_INVALID_CUOFF) {
4157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Bool found;
4158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Word ixFirst, ixLast;
4159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TempVar key;
4160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TempVar* keyp = &key;
4161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TempVar *varAI;
4162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(memset)(&key, 0, sizeof(key)); /* not necessary */
4163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         key.dioff = varp->absOri; /* this is what we want to find */
4164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         found = VG_(lookupXA)( dioff_lookup_tab, &keyp,
4165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                &ixFirst, &ixLast );
4166bdee918842b4b2d4a09146a4642e999dc71b3652sewardj         if (!found) {
4167bdee918842b4b2d4a09146a4642e999dc71b3652sewardj            /* barf("DW_AT_abstract_origin can't be resolved"); */
4168bdee918842b4b2d4a09146a4642e999dc71b3652sewardj            TRACE_D3("  SKIP (DW_AT_abstract_origin can't be resolved)\n\n");
4169bdee918842b4b2d4a09146a4642e999dc71b3652sewardj            continue;
4170bdee918842b4b2d4a09146a4642e999dc71b3652sewardj         }
4171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* If the following fails, there is more than one entry with
4172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            the same dioff.  Which can't happen. */
4173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vg_assert(ixFirst == ixLast);
4174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         varAI = *(TempVar**)VG_(indexXA)( dioff_lookup_tab, ixFirst );
4175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* stay sane */
4176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vg_assert(varAI);
4177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vg_assert(varAI->dioff == varp->absOri);
4178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* Copy what useful info we can. */
4180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (varAI->typeR && !varp->typeR)
4181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            varp->typeR = varAI->typeR;
4182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (varAI->name && !varp->name)
4183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            varp->name = varAI->name;
4184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (varAI->fName && !varp->fName)
4185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            varp->fName = varAI->fName;
4186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (varAI->fLine > 0 && varp->fLine == 0)
4187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            varp->fLine = varAI->fLine;
4188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Give it a name if it doesn't have one. */
4191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (!varp->name)
4192b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         varp->name = ML_(addStr)( di, "<anon_var>", -1 );
4193b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4194b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* So now does it have enough info to be useful? */
41959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* NOTE: re typeR: this is a hack.  If typeR is Te_UNKNOWN then
41969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         the type didn't get resolved.  Really, in that case
41979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         something's broken earlier on, and should be fixed, rather
41989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         than just skipping the variable. */
41999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      ent = ML_(TyEnts__index_by_cuOff)( tyents_to_keep,
42009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                         tyents_to_keep_cache,
42019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                         varp->typeR );
42029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* The next two assertions should be guaranteed by
42039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         our previous call to resolve_variable_types. */
42049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ent);
42059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ML_(TyEnt__is_type)(ent) || ent->tag == Te_UNKNOWN);
42069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
42079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (ent->tag == Te_UNKNOWN) continue;
42089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
4209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(varp->gexpr);
4210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(varp->name);
4211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(varp->typeR);
4212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(varp->level >= 0);
4213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Ok.  So we're going to keep it.  Call ML_(addVar) once for
4215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         each address range in which the variable exists. */
4216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("  ACQUIRE for range(s) ");
4217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      { AddrRange  oneRange;
4218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        AddrRange* varPcRanges;
4219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        Word       nVarPcRanges;
4220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        /* Set up to iterate over address ranges, however
4221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           represented. */
4222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        if (varp->nRanges == 0 || varp->nRanges == 1) {
4223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           vg_assert(!varp->rngMany);
4224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           if (varp->nRanges == 0) {
4225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              vg_assert(varp->rngOneMin == 0);
4226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              vg_assert(varp->rngOneMax == 0);
4227b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           }
4228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           nVarPcRanges = varp->nRanges;
4229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           oneRange.aMin = varp->rngOneMin;
4230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           oneRange.aMax = varp->rngOneMax;
4231b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           varPcRanges = &oneRange;
4232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        } else {
4233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           vg_assert(varp->rngMany);
4234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           vg_assert(varp->rngOneMin == 0);
4235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           vg_assert(varp->rngOneMax == 0);
4236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           nVarPcRanges = VG_(sizeXA)(varp->rngMany);
4237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           vg_assert(nVarPcRanges >= 2);
4238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           vg_assert(nVarPcRanges == (Word)varp->nRanges);
4239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           varPcRanges = VG_(indexXA)(varp->rngMany, 0);
4240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        }
4241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        if (varp->level == 0)
4242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           vg_assert( nVarPcRanges == 1 );
4243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        /* and iterate */
4244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        for (i = 0; i < nVarPcRanges; i++) {
4245b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           Addr pcMin = varPcRanges[i].aMin;
4246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           Addr pcMax = varPcRanges[i].aMax;
4247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           vg_assert(pcMin <= pcMax);
4248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           /* Level 0 is the global address range.  So at level 0 we
4249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              don't want to bias pcMin/pcMax; but at all other levels
4250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              we do since those are derived from svmas in the Dwarf
4251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              we're reading.  Be paranoid ... */
4252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           if (varp->level == 0) {
4253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              vg_assert(pcMin == (Addr)0);
4254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              vg_assert(pcMax == ~(Addr)0);
4255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           } else {
4256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              /* vg_assert(pcMin > (Addr)0);
4257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                 No .. we can legitimately expect to see ranges like
4258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                 0x0-0x11D (pre-biasing, of course). */
4259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              vg_assert(pcMax < ~(Addr)0);
4260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           }
4261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
426268a2ebd9384661a85a4674fe8310c595ad494305sewardj           /* Apply text biasing, for non-global variables. */
426368a2ebd9384661a85a4674fe8310c595ad494305sewardj           if (varp->level > 0) {
4264402c9eed11b9b60c6e134d05db938e395466cf99tom              pcMin += di->text_debug_bias;
4265402c9eed11b9b60c6e134d05db938e395466cf99tom              pcMax += di->text_debug_bias;
426668a2ebd9384661a85a4674fe8310c595ad494305sewardj           }
426768a2ebd9384661a85a4674fe8310c595ad494305sewardj
426868a2ebd9384661a85a4674fe8310c595ad494305sewardj           if (i > 0 && (i%2) == 0)
426968a2ebd9384661a85a4674fe8310c595ad494305sewardj              TRACE_D3("\n                       ");
4270a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart           TRACE_D3("[%#lx,%#lx] ", pcMin, pcMax );
4271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           ML_(addVar)(
4273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              di, varp->level,
427468a2ebd9384661a85a4674fe8310c595ad494305sewardj                  pcMin, pcMax,
42759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                  varp->name,  varp->typeR,
4276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  varp->gexpr, varp->fbGX,
4277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  varp->fName, varp->fLine, td3
4278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           );
4279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        }
4280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("\n\n");
4283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* and move on to the next var */
4284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Now free all the TempVars */
428759a2d18d0ddfa241850017252b0804d469187d79sewardj   n = VG_(sizeXA)( tempvars );
428859a2d18d0ddfa241850017252b0804d469187d79sewardj   for (i = 0; i < n; i++) {
428959a2d18d0ddfa241850017252b0804d469187d79sewardj      varp = *(TempVar**)VG_(indexXA)( tempvars, i );
4290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ML_(dinfo_free)(varp);
4291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
429259a2d18d0ddfa241850017252b0804d469187d79sewardj   VG_(deleteXA)( tempvars );
4293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   tempvars = NULL;
4294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
42959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* and the temp lookup table */
4296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(deleteXA)( dioff_lookup_tab );
4297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
42989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* and the ranges tree.  Note that we need to also free the XArrays
42999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      which constitute the keys, hence pass VG_(deleteXA) as a
43009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      key-finalizer. */
43019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(deleteFM)( rangestree, (void(*)(UWord))VG_(deleteXA), NULL );
43029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
43039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* and the tyents_to_keep cache */
43049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   ML_(dinfo_free)( tyents_to_keep_cache );
43059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   tyents_to_keep_cache = NULL;
43069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
4307d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   vg_assert( varparser.filenameTable == NULL );
4308d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4309d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   /* And the signatured type hash.  */
4310d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   VG_(HT_destruct) ( signature_types, ML_(dinfo_free) );
43119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
43129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* record the GExprs in di so they can be freed later */
4313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(!di->admin_gexprs);
4314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   di->admin_gexprs = gexprs;
4315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
4319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
4320b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- The "new" DWARF3 reader -- top level control logic   ---*/
4321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
4322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
4323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
43246c591e15c1d6402a2a755310f005f795b68e7e38sewardjstatic Bool               d3rd_jmpbuf_valid  = False;
43256bd9dc18c043927c1196caba20a327238a179c42florianstatic const HChar*       d3rd_jmpbuf_reason = NULL;
432697d3ebba515c00930db4ee3f52af571bc84b2ef6sewardjstatic VG_MINIMAL_JMP_BUF(d3rd_jmpbuf);
4327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
43286bd9dc18c043927c1196caba20a327238a179c42florianstatic __attribute__((noreturn)) void barf ( const HChar* reason ) {
4329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(d3rd_jmpbuf_valid);
4330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   d3rd_jmpbuf_reason = reason;
43316c591e15c1d6402a2a755310f005f795b68e7e38sewardj   VG_MINIMAL_LONGJMP(d3rd_jmpbuf);
4332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
4333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(0);
4334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid
4338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjML_(new_dwarf3_reader) (
4339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct _DebugInfo* di,
43405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_info,      DiSlice escn_debug_types,
43415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_abbv,      DiSlice escn_debug_line,
43425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_str,       DiSlice escn_debug_ranges,
43435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_loc,       DiSlice escn_debug_info_alt,
43445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_abbv_alt,  DiSlice escn_debug_line_alt,
43455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_str_alt
4346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj)
4347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   volatile Int  jumped;
4349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   volatile Bool td3 = di->trace_symtab;
4350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Run the _wrk function to read the dwarf3.  If it succeeds, it
4352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      just returns normally.  If there is any failure, it longjmp's
4353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      back here, having first set d3rd_jmpbuf_reason to something
4354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      useful. */
4355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(d3rd_jmpbuf_valid  == False);
4356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(d3rd_jmpbuf_reason == NULL);
4357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   d3rd_jmpbuf_valid = True;
43596c591e15c1d6402a2a755310f005f795b68e7e38sewardj   jumped = VG_MINIMAL_SETJMP(d3rd_jmpbuf);
4360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (jumped == 0) {
4361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* try this ... */
4362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      new_dwarf3_reader_wrk( di, barf,
43635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             escn_debug_info,     escn_debug_types,
43645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             escn_debug_abbv,     escn_debug_line,
43655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             escn_debug_str,      escn_debug_ranges,
43665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             escn_debug_loc,      escn_debug_info_alt,
43675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             escn_debug_abbv_alt, escn_debug_line_alt,
43685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             escn_debug_str_alt );
4369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      d3rd_jmpbuf_valid = False;
4370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("\n------ .debug_info reading was successful ------\n");
4371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } else {
4372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* It longjmp'd. */
4373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      d3rd_jmpbuf_valid = False;
4374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Can't longjump without giving some sort of reason. */
4375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(d3rd_jmpbuf_reason != NULL);
4376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("\n------ .debug_info reading failed ------\n");
4378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ML_(symerr)(di, True, d3rd_jmpbuf_reason);
4380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   d3rd_jmpbuf_valid  = False;
4383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   d3rd_jmpbuf_reason = NULL;
4384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* --- Unused code fragments which might be useful one day. --- */
4389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#if 0
4391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Read the arange tables */
4392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n");
4393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n------ The contents of .debug_arange ------\n");
4394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   init_Cursor( &aranges, debug_aranges_img,
4395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                debug_aranges_sz, 0, barf,
4396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                "Overrun whilst reading .debug_aranges section" );
4397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
4398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ULong  len, d_i_offset;
4399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   is64;
4400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UShort version;
4401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar  asize, segsize;
4402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (is_at_end_Cursor( &aranges ))
4404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
4405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Read one arange thingy */
4406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* initial_length field */
4407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      len = get_Initial_Length( &is64, &aranges,
4408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               "in .debug_aranges: invalid initial-length field" );
4409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      version    = get_UShort( &aranges );
4410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      d_i_offset = get_Dwarfish_UWord( &aranges, is64 );
4411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      asize      = get_UChar( &aranges );
4412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      segsize    = get_UChar( &aranges );
4413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("  Length:                   %llu\n", len);
4414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("  Version:                  %d\n", (Int)version);
4415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("  Offset into .debug_info:  %llx\n", d_i_offset);
4416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("  Pointer Size:             %d\n", (Int)asize);
4417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("  Segment Size:             %d\n", (Int)segsize);
4418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("\n");
4419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("    Address            Length\n");
4420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while ((get_position_of_Cursor( &aranges ) % (2 * asize)) > 0) {
4422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (void)get_UChar( & aranges );
4423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
4425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ULong address = get_Dwarfish_UWord( &aranges, asize==8 );
4426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ULong length = get_Dwarfish_UWord( &aranges, asize==8 );
4427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("    0x%016llx 0x%llx\n", address, length);
4428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (address == 0 && length == 0) break;
4429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n");
4432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
4433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
44348b68b64759254d514d98328c496cbd88cde4c9a5njn#endif // defined(VGO_linux) || defined(VGO_darwin)
4435f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
4436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------------*/
44378b68b64759254d514d98328c496cbd88cde4c9a5njn/*--- end                                                          ---*/
4438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------------*/
4439