1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Read DWARF3/4 ".debug_info" sections (DIE trees).            ---*/
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                 readdwarf3.c ---*/
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This file is part of Valgrind, a dynamic binary instrumentation
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   framework.
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
11b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Copyright (C) 2008-2011 OpenWorks LLP
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      info@open-works.co.uk
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is free software; you can redistribute it and/or
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   modify it under the terms of the GNU General Public License as
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   published by the Free Software Foundation; either version 2 of the
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   License, or (at your option) any later version.
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is distributed in the hope that it will be useful, but
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   WITHOUT ANY WARRANTY; without even the implied warranty of
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   General Public License for more details.
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   You should have received a copy of the GNU General Public License
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   along with this program; if not, write to the Free Software
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   02111-1307, USA.
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The GNU General Public License is contained in the file COPYING.
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Neither the names of the U.S. Department of Energy nor the
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   University of California nor the names of its contributors may be
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   used to endorse or promote products derived from this software
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   without prior written permission.
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) || defined(VGO_darwin)
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* REFERENCE (without which this code will not make much sense):
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DWARF Debugging Information Format, Version 3,
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   dated 20 December 2005 (the "D3 spec").
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Available at http://www.dwarfstd.org/Dwarf3.pdf.  There's also a
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   .doc (MS Word) version, but for some reason the section numbers
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   between the Word and PDF versions differ by 1 in the first digit.
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   All section references in this code are to the PDF version.
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   CURRENT HACKS:
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DW_TAG_{const,volatile}_type no DW_AT_type is allowed; it is
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      assumed to mean "const void" or "volatile void" respectively.
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      GDB appears to interpret them like this, anyway.
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   In many cases it is important to know the svma of a CU (the "base
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   address of the CU", as the D3 spec calls it).  There are some
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   situations in which the spec implies this value is unknown, but the
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Dwarf3 produced by gcc-4.1 seems to assume is not unknown but
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   merely zero when not explicitly stated.  So we too have to make
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   that assumption.
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POTENTIAL BUG?  Spotted 6 Sept 08.  Why doesn't
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   unitary_range_list() bias the resulting range list in the same way
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   that its more general cousin, get_range_list(), does?  I don't
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   know.
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TODO, 2008 Feb 17:
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   get rid of cu_svma_known and document the assumed-zero svma hack.
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(sizeOfType): differentiate between zero sized types and types
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for which the size is unknown.  Is this important?  I don't know.
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DW_AT_array_types: deal with explicit sizes (currently we compute
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the size from the bounds and the element size, although that's
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   fragile, if the bounds incompletely specified, or completely
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   absent)
78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Document reason for difference (by 1) of stack preening depth in
80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   parse_var_DIE vs parse_type_DIE.
81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Don't hand to ML_(addVars), vars whose locations are entirely in
83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   registers (DW_OP_reg*).  This is merely a space-saving
84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   optimisation, as ML_(evaluate_Dwarf3_Expr) should handle these
85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   expressions correctly, by failing to evaluate them and hence
86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   effectively ignoring the variable with which they are associated.
87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Deal with DW_AT_array_types which have element size != stride
89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   In some cases, the info for a variable is split between two
91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   different DIEs (generally a declarer and a definer).  We punt on
92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   these.  Could do better here.
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The 'data_bias' argument passed to the expression evaluator
95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (ML_(evaluate_Dwarf3_Expr)) should really be changed to a
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MaybeUWord, to make it clear when we do vs don't know what it is
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for the evaluation of an expression.  At the moment zero is passed
98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for this parameter in the don't know case.  That's a bit fragile
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   and obscure; using a MaybeUWord would be clearer.
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   POTENTIAL PERFORMANCE IMPROVEMENTS:
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Currently, duplicate removal and all other queries for the type
104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   entities array is done using cuOffset-based pointing, which
105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   involves a binary search (VG_(lookupXA)) for each access.  This is
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   wildly inefficient, although simple.  It would be better to
107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   translate all the cuOffset-based references (iow, all the "R" and
108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   "Rs" fields in the TyEnts in 'tyents') to direct index numbers in
109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   'tyents' right at the start of dedup_types(), and use direct
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   indexing (VG_(indexXA)) wherever possible after that.
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   cmp__XArrays_of_AddrRange is also a performance bottleneck.  Move
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(indexXA) into pub_tool_xarray.h so it can be inlined at all use
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   points, and possibly also make an _UNCHECKED version which skips
115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the range checks in performance-critical situations such as this.
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Handle interaction between read_DIE and parse_{var,type}_DIE
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   better.  Currently read_DIE reads the entire DIE just to find where
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the end is (and for debug printing), so that it can later reliably
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   move the cursor to the end regardless of what parse_{var,type}_DIE
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do.  This means many DIEs (most, even?) are read twice.  It would
122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   be smarter to make parse_{var,type}_DIE return a Bool indicating
123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   whether or not they advanced the DIE cursor, and only if they
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   didn't should read_DIE itself read through the DIE.
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(addVar) and add_var_to_arange: quite a lot of DiAddrRanges have
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   zero variables in their .vars XArray.  Rather than have an XArray
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   with zero elements (which uses 2 malloc'd blocks), allow the .vars
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pointer to be NULL in this case.
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   More generally, reduce the amount of memory allocated and freed
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while reading Dwarf3 type/variable information.  Even modest (20MB)
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   objects cause this module to allocate and free hundreds of
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   thousands of small blocks, and ML_(arena_malloc) and its various
135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   groupies always show up at the top of performance profiles. */
136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_basics.h"
138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_debuginfo.h"
139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcbase.h"
140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcassert.h"
141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcprint.h"
142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_libcsetjmp.h"   // setjmp facilities
143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_options.h"
144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_tooliface.h"    /* VG_(needs) */
145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_xarray.h"
146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_wordfm.h"
147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "priv_misc.h"             /* dinfo_zalloc/free */
148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "priv_tytypes.h"
149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "priv_d3basics.h"
150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "priv_storage.h"
151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "priv_readdwarf3.h"       /* self */
152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Basic machinery for parsing DIEs.                    ---*/
157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define TRACE_D3(format, args...) \
161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (td3) { VG_(printf)(format, ## args); }
162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define D3_INVALID_CUOFF  ((UWord)(-1UL))
164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define D3_FAKEVOID_CUOFF ((UWord)(-2UL))
165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar* region_start_img;
169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord  region_szB;
170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord  region_next;
171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      void (*barf)( HChar* ) __attribute__((noreturn));
172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      HChar* barfstr;
173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Cursor;
175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline Bool is_sane_Cursor ( Cursor* c ) {
177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!c)                return False;
178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!c->barf)          return False;
179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!c->barfstr)       return False;
180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return True;
181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void init_Cursor ( Cursor* c,
184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          UChar*  region_start_img,
185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          UWord   region_szB,
186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          UWord   region_next,
187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          __attribute__((noreturn)) void (*barf)( HChar* ),
188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          HChar*  barfstr )
189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(c);
191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(memset)(c, 0, sizeof(*c));
192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   c->region_start_img = region_start_img;
193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   c->region_szB       = region_szB;
194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   c->region_next      = region_next;
195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   c->barf             = barf;
196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   c->barfstr          = barfstr;
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(is_sane_Cursor(c));
198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool is_at_end_Cursor ( Cursor* c ) {
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(is_sane_Cursor(c));
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return c->region_next >= c->region_szB;
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UWord get_position_of_Cursor ( Cursor* c ) {
206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(is_sane_Cursor(c));
207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return c->region_next;
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline void set_position_of_Cursor ( Cursor* c, UWord pos ) {
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   c->region_next = pos;
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(is_sane_Cursor(c));
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic /*signed*/Word get_remaining_length_Cursor ( Cursor* c ) {
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(is_sane_Cursor(c));
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return c->region_szB - c->region_next;
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UChar* get_address_of_Cursor ( Cursor* c ) {
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(is_sane_Cursor(c));
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return &c->region_start_img[ c->region_next ];
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* FIXME: document assumptions on endianness for
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   get_UShort/UInt/ULong. */
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UChar get_UChar ( Cursor* c ) {
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar r;
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* vg_assert(is_sane_Cursor(c)); */
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c->region_next + sizeof(UChar) > c->region_szB) {
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      c->barf(c->barfstr);
231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /*NOTREACHED*/
232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(0);
233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   r = * (UChar*) &c->region_start_img[ c->region_next ];
235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   c->region_next += sizeof(UChar);
236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return r;
237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UShort get_UShort ( Cursor* c ) {
239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UShort r;
240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(is_sane_Cursor(c));
241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c->region_next + sizeof(UShort) > c->region_szB) {
242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      c->barf(c->barfstr);
243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /*NOTREACHED*/
244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(0);
245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   r = ML_(read_UShort)(&c->region_start_img[ c->region_next ]);
247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   c->region_next += sizeof(UShort);
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return r;
249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt get_UInt ( Cursor* c ) {
251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt r;
252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(is_sane_Cursor(c));
253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c->region_next + sizeof(UInt) > c->region_szB) {
254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      c->barf(c->barfstr);
255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /*NOTREACHED*/
256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(0);
257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   r = ML_(read_UInt)(&c->region_start_img[ c->region_next ]);
259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   c->region_next += sizeof(UInt);
260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return r;
261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic ULong get_ULong ( Cursor* c ) {
263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ULong r;
264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(is_sane_Cursor(c));
265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (c->region_next + sizeof(ULong) > c->region_szB) {
266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      c->barf(c->barfstr);
267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /*NOTREACHED*/
268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(0);
269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   r = ML_(read_ULong)(&c->region_start_img[ c->region_next ]);
271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   c->region_next += sizeof(ULong);
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return r;
273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline ULong get_ULEB128 ( Cursor* c ) {
275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ULong result;
276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int   shift;
277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar byte;
278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* unroll first iteration */
279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   byte = get_UChar( c );
280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   result = (ULong)(byte & 0x7f);
281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (LIKELY(!(byte & 0x80))) return result;
282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   shift = 7;
283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* end unroll first iteration */
284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {
285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      byte = get_UChar( c );
286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      result |= ((ULong)(byte & 0x7f)) << shift;
287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      shift += 7;
288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (byte & 0x80);
289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return result;
290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Long get_SLEB128 ( Cursor* c ) {
292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ULong  result = 0;
293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int    shift = 0;
294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar  byte;
295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {
296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      byte = get_UChar(c);
297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      result |= ((ULong)(byte & 0x7f)) << shift;
298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      shift += 7;
299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (byte & 0x80);
300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (shift < 64 && (byte & 0x40))
301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      result |= -(1ULL << shift);
302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return result;
303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Assume 'c' points to the start of a string.  Return the absolute
306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   address of whatever it points at, and advance it past the
307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   terminating zero.  This makes it safe for the caller to then copy
308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the string with ML_(addStr), since (w.r.t. image overruns) the
309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   process of advancing past the terminating zero will already have
310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   "vetted" the string. */
311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UChar* get_AsciiZ ( Cursor* c ) {
312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar  uc;
313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar* res = get_address_of_Cursor(c);
314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do { uc = get_UChar(c); } while (uc != 0);
315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return res;
316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic ULong peek_ULEB128 ( Cursor* c ) {
319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Word here = c->region_next;
320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ULong r = get_ULEB128( c );
321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   c->region_next = here;
322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return r;
323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UChar peek_UChar ( Cursor* c ) {
325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Word here = c->region_next;
326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar r = get_UChar( c );
327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   c->region_next = here;
328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return r;
329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic ULong get_Dwarfish_UWord ( Cursor* c, Bool is_dw64 ) {
332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return is_dw64 ? get_ULong(c) : (ULong) get_UInt(c);
333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UWord get_UWord ( Cursor* c ) {
336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(sizeof(UWord) == sizeof(void*));
337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (sizeof(UWord) == 4) return get_UInt(c);
338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (sizeof(UWord) == 8) return get_ULong(c);
339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(0);
340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Read a DWARF3 'Initial Length' field */
343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic ULong get_Initial_Length ( /*OUT*/Bool* is64,
344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  Cursor* c,
345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  HChar* barfMsg )
346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ULong w64;
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  w32;
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *is64 = False;
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w32 = get_UInt( c );
351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (w32 >= 0xFFFFFFF0 && w32 < 0xFFFFFFFF) {
352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      c->barf( barfMsg );
353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   else if (w32 == 0xFFFFFFFF) {
355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *is64 = True;
356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      w64   = get_ULong( c );
357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *is64 = False;
359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      w64 = (ULong)w32;
360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return w64;
362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- "CUConst" structure                                  ---*/
368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define N_ABBV_CACHE 32
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Holds information that is constant through the parsing of a
374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Compilation Unit.  This is basically plumbed through to
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   everywhere. */
376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Call here if anything goes wrong */
379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      void (*barf)( HChar* ) __attribute__((noreturn));
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Is this 64-bit DWARF ? */
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool   is_dw64;
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Which DWARF version ?  (2, 3 or 4) */
383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UShort version;
384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Length of this Compilation Unit, as stated in the
385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         .unit_length :: InitialLength field of the CU Header.
386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         However, this size (as specified by the D3 spec) does not
387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         include the size of the .unit_length field itself, which is
388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         either 4 or 12 bytes (32-bit or 64-bit Dwarf3).  That value
389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         can be obtained through the expression ".is_dw64 ? 12 : 4". */
390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ULong  unit_length;
391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Offset of start of this unit in .debug_info */
392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord  cu_start_offset;
393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* SVMA for this CU.  In the D3 spec, is known as the "base
394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         address of the compilation unit (last para sec 3.1.1).
395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Needed for (amongst things) interpretation of location-list
396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         values. */
397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr   cu_svma;
398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool   cu_svma_known;
399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* The debug_abbreviations table to be used for this Unit */
400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar* debug_abbv;
401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Upper bound on size thereof (an overestimate, in general) */
402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord  debug_abbv_maxszB;
403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Where is .debug_str ? */
404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar* debug_str_img;
405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord  debug_str_sz;
406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Where is .debug_ranges ? */
407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar* debug_ranges_img;
408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord  debug_ranges_sz;
409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Where is .debug_loc ? */
410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar* debug_loc_img;
411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord  debug_loc_sz;
412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Where is .debug_line? */
413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar* debug_line_img;
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord  debug_line_sz;
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Where is .debug_info? */
416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar* debug_info_img;
417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord  debug_info_sz;
418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* --- Needed so we can add stuff to the string table. --- */
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct _DebugInfo* di;
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* --- a cache for set_abbv_Cursor --- */
421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* abbv_code == (ULong)-1 for an unused entry. */
422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct { ULong abbv_code; UWord posn; } saC_cache[N_ABBV_CACHE];
423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord saC_cache_queries;
424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord saC_cache_misses;
425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   CUConst;
427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Helper functions for Guarded Expressions             ---*/
432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Parse the location list starting at img-offset 'debug_loc_offset'
436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   in .debug_loc.  Results are biased with 'svma_of_referencing_CU'
437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   and so I believe are correct SVMAs for the object as a whole.  This
438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   function allocates the UChar*, and the caller must deallocate it.
439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The resulting block is in so-called Guarded-Expression format.
440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Guarded-Expression format is similar but not identical to the DWARF3
442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   location-list format.  The format of each returned block is:
443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar biasMe;
445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar isEnd;
446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      followed by zero or more of
447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (Addr aMin;  Addr aMax;  UShort nbytes;  ..bytes..;  UChar isEnd)
449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   '..bytes..' is an standard DWARF3 location expression which is
451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   valid when aMin <= pc <= aMax (possibly after suitable biasing).
452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The number of bytes in '..bytes..' is nbytes.
454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The end of the sequence is marked by an isEnd == 1 value.  All
456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   previous isEnd values must be zero.
457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   biasMe is 1 if the aMin/aMax fields need this DebugInfo's
459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   text_bias added before use, and 0 if the GX is this is not
460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   necessary (is ready to go).
461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Hence the block can be quickly parsed and is self-describing.  Note
463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   that aMax is 1 less than the corresponding value in a DWARF3
464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   location list.  Zero length ranges, with aMax == aMin-1, are not
465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   allowed.
466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 2008-sept-12: moved ML_(pp_GX) from here to d3basics.c, where
468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   it more logically belongs. */
469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Apply a text bias to a GX. */
472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void bias_GX ( /*MOD*/GExpr* gx, struct _DebugInfo* di )
473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UShort nbytes;
475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar* p = &gx->payload[0];
476b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UChar* pA;
477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar  uc;
478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   uc = *p++; /*biasMe*/
479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (uc == 0)
480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return;
481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(uc == 1);
482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   p[-1] = 0; /* mark it as done */
483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (True) {
484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      uc = *p++;
485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (uc == 1)
486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break; /*isEnd*/
487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(uc == 0);
488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* t-bias aMin */
489b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      pA = (UChar*)p;
490b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ML_(write_Addr)(pA, ML_(read_Addr)(pA) + di->text_debug_bias);
491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p += sizeof(Addr);
492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* t-bias aMax */
493b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      pA = (UChar*)p;
494b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ML_(write_Addr)(pA, ML_(read_Addr)(pA) + di->text_debug_bias);
495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p += sizeof(Addr);
496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* nbytes, and actual expression */
497b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      nbytes = ML_(read_UShort)(p); p += sizeof(UShort);
498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p += nbytes;
499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline))
503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic GExpr* make_singleton_GX ( UChar* block, UWord nbytes )
504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT  bytesReqd;
506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GExpr* gx;
507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar *p, *pstart;
508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(sizeof(UWord) == sizeof(Addr));
510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(nbytes <= 0xFFFF); /* else we overflow the nbytes field */
511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   bytesReqd
512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      =   sizeof(UChar)  /*biasMe*/    + sizeof(UChar) /*!isEnd*/
513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        + sizeof(UWord)  /*aMin*/      + sizeof(UWord) /*aMax*/
514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        + sizeof(UShort) /*nbytes*/    + nbytes
515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        + sizeof(UChar); /*isEnd*/
516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   gx = ML_(dinfo_zalloc)( "di.readdwarf3.msGX.1",
518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           sizeof(GExpr) + bytesReqd );
519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(gx);
520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   p = pstart = &gx->payload[0];
522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
523b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   p = ML_(write_UChar)(p, 0);        /*biasMe*/
524b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   p = ML_(write_UChar)(p, 0);        /*!isEnd*/
525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   p = ML_(write_Addr)(p, 0);         /*aMin*/
526b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   p = ML_(write_Addr)(p, ~0);        /*aMax*/
527b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   p = ML_(write_UShort)(p, nbytes);  /*nbytes*/
528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(memcpy)(p, block, nbytes); p += nbytes;
529b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   p = ML_(write_UChar)(p, 1);        /*isEnd*/
530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( (SizeT)(p - pstart) == bytesReqd);
532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( &gx->payload[bytesReqd]
533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              == ((UChar*)gx) + sizeof(GExpr) + bytesReqd );
534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return gx;
536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline))
539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic GExpr* make_general_GX ( CUConst* cc,
540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                Bool     td3,
541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                UWord    debug_loc_offset,
542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                Addr     svma_of_referencing_CU )
543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr      base;
545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Cursor    loc;
546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   XArray*   xa; /* XArray of UChar */
547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GExpr*    gx;
548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Word      nbytes;
549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(sizeof(UWord) == sizeof(Addr));
551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (cc->debug_loc_sz == 0)
552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc->barf("make_general_GX: .debug_loc is empty/missing");
553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   init_Cursor( &loc, cc->debug_loc_img,
555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                cc->debug_loc_sz, 0, cc->barf,
556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                "Overrun whilst reading .debug_loc section(2)" );
557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   set_position_of_Cursor( &loc, debug_loc_offset );
558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_D3("make_general_GX (.debug_loc_offset = %lu, img = %p) {\n",
560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            debug_loc_offset, get_address_of_Cursor( &loc ) );
561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Who frees this xa?  It is freed before this fn exits. */
563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.mgGX.1",
564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    ML_(dinfo_free),
565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    sizeof(UChar) );
566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { UChar c = 1; /*biasMe*/ VG_(addBytesToXA)( xa, &c, sizeof(c) ); }
568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   base = 0;
570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (True) {
571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool  acquire;
572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord len;
573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Read a (host-)word pair.  This is something of a hack since
574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         the word size to read is really dictated by the ELF file;
575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         however, we assume we're reading a file with the same
576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         word-sizeness as the host.  Reasonably enough. */
577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord w1 = get_UWord( &loc );
578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord w2 = get_UWord( &loc );
579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("   %08lx %08lx\n", w1, w2);
581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (w1 == 0 && w2 == 0)
582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break; /* end of list */
583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (w1 == -1UL) {
585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* new value for 'base' */
586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         base = w2;
587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         continue;
588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* else a location expression follows */
591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* else enumerate [w1+base, w2+base) */
592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* w2 is 1 past end of range, as per D3 defn for "DW_AT_high_pc"
593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (sec 2.17.2) */
594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (w1 > w2) {
595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("negative range is for .debug_loc expr at "
596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  "file offset %lu\n",
597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  debug_loc_offset);
598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         cc->barf( "negative range in .debug_loc section" );
599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ignore zero length ranges */
602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      acquire = w1 < w2;
603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      len     = (UWord)get_UShort( &loc );
604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (acquire) {
606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UWord  w;
607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UShort s;
608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UChar  c;
609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         c = 0; /* !isEnd*/
610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(addBytesToXA)( xa, &c, sizeof(c) );
611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         w = w1    + base + svma_of_referencing_CU;
612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(addBytesToXA)( xa, &w, sizeof(w) );
613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         w = w2 -1 + base + svma_of_referencing_CU;
614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(addBytesToXA)( xa, &w, sizeof(w) );
615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         s = (UShort)len;
616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(addBytesToXA)( xa, &s, sizeof(s) );
617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (len > 0) {
620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UChar byte = get_UChar( &loc );
621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("%02x", (UInt)byte);
622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (acquire)
623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_(addBytesToXA)( xa, &byte, 1 );
624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         len--;
625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("\n");
627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { UChar c = 1; /*isEnd*/ VG_(addBytesToXA)( xa, &c, sizeof(c) ); }
630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   nbytes = VG_(sizeXA)( xa );
632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(nbytes >= 1);
633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   gx = ML_(dinfo_zalloc)( "di.readdwarf3.mgGX.2", sizeof(GExpr) + nbytes );
635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(gx);
636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(memcpy)( &gx->payload[0], (UChar*)VG_(indexXA)(xa,0), nbytes );
637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( &gx->payload[nbytes]
638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              == ((UChar*)gx) + sizeof(GExpr) + nbytes );
639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(deleteXA)( xa );
641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_D3("}\n");
643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return gx;
645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Helper functions for range lists and CU headers      ---*/
651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Denotes an address range.  Both aMin and aMax are included in the
655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   range; hence a complete range is (0, ~0) and an empty range is any
656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (X, X-1) for X > 0.*/
657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct { Addr aMin; Addr aMax; }
659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AddrRange;
660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Generate an arbitrary structural total ordering on
663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   XArray* of AddrRange. */
664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Word cmp__XArrays_of_AddrRange ( XArray* rngs1, XArray* rngs2 )
665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Word n1, n2, i;
667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tl_assert(rngs1 && rngs2);
668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n1 = VG_(sizeXA)( rngs1 );
669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n2 = VG_(sizeXA)( rngs2 );
670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (n1 < n2) return -1;
671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (n1 > n2) return 1;
672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < n1; i++) {
673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      AddrRange* rng1 = (AddrRange*)VG_(indexXA)( rngs1, i );
674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      AddrRange* rng2 = (AddrRange*)VG_(indexXA)( rngs2, i );
675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (rng1->aMin < rng2->aMin) return -1;
676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (rng1->aMin > rng2->aMin) return 1;
677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (rng1->aMax < rng2->aMax) return -1;
678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (rng1->aMax > rng2->aMax) return 1;
679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return 0;
681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline))
685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic XArray* /* of AddrRange */ empty_range_list ( void )
686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   XArray* xa; /* XArray of AddrRange */
688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Who frees this xa?  varstack_preen() does. */
689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.erl.1",
690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    ML_(dinfo_free),
691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    sizeof(AddrRange) );
692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return xa;
693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline))
697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic XArray* unitary_range_list ( Addr aMin, Addr aMax )
698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   XArray*   xa;
700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AddrRange pair;
701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(aMin <= aMax);
702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Who frees this xa?  varstack_preen() does. */
703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   xa = VG_(newXA)( ML_(dinfo_zalloc),  "di.readdwarf3.url.1",
704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    ML_(dinfo_free),
705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    sizeof(AddrRange) );
706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pair.aMin = aMin;
707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pair.aMax = aMax;
708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(addToXA)( xa, &pair );
709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return xa;
710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Enumerate the address ranges starting at img-offset
714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   'debug_ranges_offset' in .debug_ranges.  Results are biased with
715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   'svma_of_referencing_CU' and so I believe are correct SVMAs for the
716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   object as a whole.  This function allocates the XArray, and the
717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   caller must deallocate it. */
718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline))
719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic XArray* /* of AddrRange */
720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       get_range_list ( CUConst* cc,
721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        Bool     td3,
722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        UWord    debug_ranges_offset,
723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        Addr     svma_of_referencing_CU )
724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr      base;
726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Cursor    ranges;
727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   XArray*   xa; /* XArray of AddrRange */
728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   AddrRange pair;
729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (cc->debug_ranges_sz == 0)
731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc->barf("get_range_list: .debug_ranges is empty/missing");
732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   init_Cursor( &ranges, cc->debug_ranges_img,
734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                cc->debug_ranges_sz, 0, cc->barf,
735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                "Overrun whilst reading .debug_ranges section(2)" );
736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   set_position_of_Cursor( &ranges, debug_ranges_offset );
737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Who frees this xa?  varstack_preen() does. */
739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.grl.1", ML_(dinfo_free),
740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    sizeof(AddrRange) );
741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   base = 0;
742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (True) {
743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Read a (host-)word pair.  This is something of a hack since
744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         the word size to read is really dictated by the ELF file;
745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         however, we assume we're reading a file with the same
746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         word-sizeness as the host.  Reasonably enough. */
747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord w1 = get_UWord( &ranges );
748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord w2 = get_UWord( &ranges );
749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (w1 == 0 && w2 == 0)
751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break; /* end of list. */
752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (w1 == -1UL) {
754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* new value for 'base' */
755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         base = w2;
756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         continue;
757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* else enumerate [w1+base, w2+base) */
760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* w2 is 1 past end of range, as per D3 defn for "DW_AT_high_pc"
761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (sec 2.17.2) */
762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (w1 > w2)
763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         cc->barf( "negative range in .debug_ranges section" );
764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (w1 < w2) {
765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         pair.aMin = w1     + base + svma_of_referencing_CU;
766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         pair.aMax = w2 - 1 + base + svma_of_referencing_CU;
767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(pair.aMin <= pair.aMax);
768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(addToXA)( xa, &pair );
769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return xa;
772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Parse the Compilation Unit header indicated at 'c' and
776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   initialise 'cc' accordingly. */
777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic __attribute__((noinline))
778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid parse_CU_Header ( /*OUT*/CUConst* cc,
779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       Bool td3,
780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       Cursor* c,
781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       UChar* debug_abbv_img, UWord debug_abbv_sz )
782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar  address_size;
784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord  debug_abbrev_offset;
785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int    i;
786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(memset)(cc, 0, sizeof(*cc));
788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(c && c->barf);
789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   cc->barf = c->barf;
790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* initial_length field */
792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   cc->unit_length
793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      = get_Initial_Length( &cc->is_dw64, c,
794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "parse_CU_Header: invalid initial-length field" );
795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_D3("   Length:        %lld\n", cc->unit_length );
797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* version */
799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   cc->version = get_UShort( c );
800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (cc->version != 2 && cc->version != 3 && cc->version != 4)
801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc->barf( "parse_CU_Header: is neither DWARF2 nor DWARF3 nor DWARF4" );
802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_D3("   Version:       %d\n", (Int)cc->version );
803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* debug_abbrev_offset */
805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   debug_abbrev_offset = get_Dwarfish_UWord( c, cc->is_dw64 );
806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (debug_abbrev_offset >= debug_abbv_sz)
807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc->barf( "parse_CU_Header: invalid debug_abbrev_offset" );
808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_D3("   Abbrev Offset: %ld\n", debug_abbrev_offset );
809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* address size.  If this isn't equal to the host word size, just
811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      give up.  This makes it safe to assume elsewhere that
812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      DW_FORM_addr and DW_FORM_ref_addr can be treated as a host
813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      word. */
814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   address_size = get_UChar( c );
815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (address_size != sizeof(void*))
816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc->barf( "parse_CU_Header: invalid address_size" );
817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_D3("   Pointer Size:  %d\n", (Int)address_size );
818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Set up so that cc->debug_abbv points to the relevant table for
820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      this CU.  Set the szB so that at least we can't read off the end
821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      of the debug_abbrev section -- potentially (and quite likely)
822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      too big, if this isn't the last table in the section, but at
823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      least it's safe. */
824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   cc->debug_abbv        = debug_abbv_img + debug_abbrev_offset;
825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   cc->debug_abbv_maxszB = debug_abbv_sz  - debug_abbrev_offset;
826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* and empty out the set_abbv_Cursor cache */
827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0) VG_(printf)("XXXXXX initialise set_abbv_Cursor cache\n");
828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < N_ABBV_CACHE; i++) {
829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc->saC_cache[i].abbv_code = (ULong)-1; /* unused */
830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc->saC_cache[i].posn = 0;
831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   cc->saC_cache_queries = 0;
833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   cc->saC_cache_misses = 0;
834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Set up 'c' so it is ready to parse the abbv table entry code
838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   'abbv_code' for this compilation unit.  */
839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic __attribute__((noinline))
840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid set_abbv_Cursor ( /*OUT*/Cursor* c, Bool td3,
841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       CUConst* cc, ULong abbv_code )
842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int   i;
844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ULong acode;
845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (abbv_code == 0)
847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc->barf("set_abbv_Cursor: abbv_code == 0" );
848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* (ULong)-1 is used to represent an empty cache slot.  So we can't
850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      allow it.  In any case no valid DWARF3 should make a reference
851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      to a negative abbreviation code.  [at least, they always seem to
852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      be numbered upwards from zero as far as I have seen] */
853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(abbv_code != (ULong)-1);
854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* First search the cache. */
856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0) VG_(printf)("XXXXXX search set_abbv_Cursor cache\n");
857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   cc->saC_cache_queries++;
858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < N_ABBV_CACHE; i++) {
859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* No need to test the cached abbv_codes for -1 (empty), since
860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         we just asserted that abbv_code is not -1. */
861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     if (cc->saC_cache[i].abbv_code == abbv_code) {
862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        /* Found it.  Cool.  Set up the parser using the cached
863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           position, and move this cache entry 1 step closer to the
864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           front. */
865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if (0) VG_(printf)("XXXXXX found in set_abbv_Cursor cache\n");
866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        init_Cursor( c, cc->debug_abbv,
867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     cc->debug_abbv_maxszB, cc->saC_cache[i].posn,
868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     cc->barf,
869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "Overrun whilst parsing .debug_abbrev section(1)" );
870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if (i > 0) {
871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           ULong t_abbv_code = cc->saC_cache[i].abbv_code;
872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           UWord t_posn = cc->saC_cache[i].posn;
873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           while (i > 0) {
874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              cc->saC_cache[i] = cc->saC_cache[i-1];
875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              cc->saC_cache[0].abbv_code = t_abbv_code;
876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              cc->saC_cache[0].posn = t_posn;
877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              i--;
878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           }
879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        return;
881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     }
882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* No.  It's not in the cache.  We have to search through
885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      .debug_abbrev, of course taking care to update the cache
886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      when done. */
887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   cc->saC_cache_misses++;
889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   init_Cursor( c, cc->debug_abbv, cc->debug_abbv_maxszB, 0, cc->barf,
890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               "Overrun whilst parsing .debug_abbrev section(2)" );
891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Now iterate though the table until we find the requested
893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      entry. */
894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (True) {
895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      //ULong atag;
896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      //UInt  has_children;
897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      acode = get_ULEB128( c );
898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (acode == 0) break; /* end of the table */
899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (acode == abbv_code) break; /* found it */
900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /*atag         = */ get_ULEB128( c );
901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /*has_children = */ get_UChar( c );
902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      //TRACE_D3("   %llu      %s    [%s]\n",
903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      //         acode, pp_DW_TAG(atag), pp_DW_children(has_children));
904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (True) {
905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ULong at_name = get_ULEB128( c );
906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ULong at_form = get_ULEB128( c );
907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (at_name == 0 && at_form == 0) break;
908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         //TRACE_D3("    %18s %s\n",
909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         //         pp_DW_AT(at_name), pp_DW_FORM(at_form));
910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (acode == 0) {
914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Not found.  This is fatal. */
915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc->barf("set_abbv_Cursor: abbv_code not found");
916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Otherwise, 'c' is now set correctly to parse the relevant entry,
919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      starting from the abbreviation entry's tag.  So just cache
920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the result, and return. */
921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = N_ABBV_CACHE-1; i > N_ABBV_CACHE/2; i--) {
922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc->saC_cache[i] = cc->saC_cache[i-1];
923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0) VG_(printf)("XXXXXX update set_abbv_Cursor cache\n");
925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   cc->saC_cache[N_ABBV_CACHE/2].abbv_code = abbv_code;
926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   cc->saC_cache[N_ABBV_CACHE/2].posn = get_position_of_Cursor(c);
927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* From 'c', get the Form data into the lowest 1/2/4/8 bytes of *cts.
931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   If *cts itself contains the entire result, then *ctsSzB is set to
933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   1,2,4 or 8 accordingly and *ctsMemSzB is set to zero.
934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Alternatively, the result can be a block of data (in the
936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   transiently mapped-in object, so-called "image" space).  If so then
937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the lowest sizeof(void*)/8 bytes of *cts hold a pointer to said
938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   image, *ctsSzB is zero, and *ctsMemSzB is the size of the block.
939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Unfortunately this means it is impossible to represent a zero-size
941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   image block since that would have *ctsSzB == 0 and *ctsMemSzB == 0
942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   and so is ambiguous (which case it is?)
943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Invariant on successful return:
945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (*ctsSzB > 0 && *ctsMemSzB == 0)
946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      || (*ctsSzB == 0 && *ctsMemSzB > 0)
947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic
949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid get_Form_contents ( /*OUT*/ULong* cts,
950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         /*OUT*/Int*   ctsSzB,
951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         /*OUT*/UWord* ctsMemSzB,
952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         CUConst* cc, Cursor* c,
953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         Bool td3, DW_FORM form )
954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *cts       = 0;
956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *ctsSzB    = 0;
957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *ctsMemSzB = 0;
958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (form) {
959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_data1:
960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)(UChar)get_UChar(c);
961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsSzB = 1;
962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("%u", (UInt)*cts);
963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_data2:
965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)(UShort)get_UShort(c);
966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsSzB = 2;
967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("%u", (UInt)*cts);
968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_data4:
970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)(UInt)get_UInt(c);
971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsSzB = 4;
972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("%u", (UInt)*cts);
973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_data8:
975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = get_ULong(c);
976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsSzB = 8;
977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("%llu", *cts);
978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_sec_offset:
980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)get_Dwarfish_UWord( c, cc->is_dw64 );
981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsSzB = cc->is_dw64 ? 8 : 4;
982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("%llu", *cts);
983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_sdata:
985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)(Long)get_SLEB128(c);
986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsSzB = 8;
987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("%lld", (Long)*cts);
988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_udata:
990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)(Long)get_ULEB128(c);
991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsSzB = 8;
992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("%llu", (Long)*cts);
993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_addr:
995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* note, this is a hack.  DW_FORM_addr is defined as getting
996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            a word the size of the target machine as defined by the
997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            address_size field in the CU Header.  However,
998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            parse_CU_Header() rejects all inputs except those for
999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            which address_size == sizeof(Word), hence we can just
1000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            treat it as a (host) Word.  */
1001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)(UWord)get_UWord(c);
1002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsSzB = sizeof(UWord);
1003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("0x%lx", (UWord)*cts);
1004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_ref_addr:
1007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* We make the same word-size assumption as DW_FORM_addr. */
1008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* What does this really mean?  From D3 Sec 7.5.4,
1009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            description of "reference", it would appear to reference
1010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            some other DIE, by specifying the offset from the
1011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            beginning of a .debug_info section.  The D3 spec mentions
1012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            that this might be in some other shared object and
1013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            executable.  But I don't see how the name of the other
1014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            object/exe is specified.
1015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            At least for the DW_FORM_ref_addrs created by icc11, the
1017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            references seem to be within the same object/executable.
1018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            So for the moment we merely range-check, to see that they
1019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            actually do specify a plausible offset within this
1020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            object's .debug_info, and return the value unchanged.
1021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         */
1022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)(UWord)get_UWord(c);
1023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsSzB = sizeof(UWord);
1024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("0x%lx", (UWord)*cts);
1025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (0) VG_(printf)("DW_FORM_ref_addr 0x%lx\n", (UWord)*cts);
1026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (/* the following 2 are surely impossible, but ... */
1027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             cc->debug_info_img == NULL || cc->debug_info_sz == 0
1028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             || *cts >= (ULong)cc->debug_info_sz) {
1029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            /* Hmm.  Offset is nonsensical for this object's .debug_info
1030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               section.  Be safe and reject it. */
1031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            cc->barf("get_Form_contents: DW_FORM_ref_addr points "
1032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "outside .debug_info");
1033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_strp: {
1037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* this is an offset into .debug_str */
1038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UChar* str;
1039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UWord uw = (UWord)get_Dwarfish_UWord( c, cc->is_dw64 );
1040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (cc->debug_str_img == NULL || uw >= cc->debug_str_sz)
1041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            cc->barf("get_Form_contents: DW_FORM_strp "
1042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "points outside .debug_str");
1043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* FIXME: check the entire string lies inside debug_str,
1044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            not just the first byte of it. */
1045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         str = (UChar*)cc->debug_str_img + uw;
1046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("(indirect string, offset: 0x%lx): %s", uw, str);
1047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)(UWord)str;
1048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsMemSzB = 1 + (ULong)VG_(strlen)(str);
1049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_string: {
1052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UChar* str = get_AsciiZ(c);
1053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("%s", str);
1054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)(UWord)str;
1055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* strlen is safe because get_AsciiZ already 'vetted' the
1056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            entire string */
1057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsMemSzB = 1 + (ULong)VG_(strlen)(str);
1058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_ref1: {
1061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UChar  u8 = get_UChar(c);
1062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UWord res = cc->cu_start_offset + (UWord)u8;
1063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)res;
1064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsSzB = sizeof(UWord);
1065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("<%lx>", res);
1066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_ref2: {
1069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UShort  u16 = get_UShort(c);
1070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UWord res = cc->cu_start_offset + (UWord)u16;
1071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)res;
1072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsSzB = sizeof(UWord);
1073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("<%lx>", res);
1074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_ref4: {
1077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt  u32 = get_UInt(c);
1078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UWord res = cc->cu_start_offset + (UWord)u32;
1079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)res;
1080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsSzB = sizeof(UWord);
1081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("<%lx>", res);
1082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_ref8: {
1085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ULong  u64 = get_ULong(c);
1086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UWord res = cc->cu_start_offset + (UWord)u64;
1087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)res;
1088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsSzB = sizeof(UWord);
1089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("<%lx>", res);
1090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_ref_udata: {
1093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ULong  u64 = get_ULEB128(c);
1094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UWord res = cc->cu_start_offset + (UWord)u64;
1095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)res;
1096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsSzB = sizeof(UWord);
1097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("<%lx>", res);
1098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_flag: {
1101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UChar u8 = get_UChar(c);
1102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("%u", (UInt)u8);
1103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)u8;
1104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsSzB = 1;
1105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_flag_present:
1108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("1");
1109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = 1;
1110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsSzB = 1;
1111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_block1: {
1113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ULong  u64b;
1114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ULong  u64 = (ULong)get_UChar(c);
1115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UChar* block = get_address_of_Cursor(c);
1116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("%llu byte block: ", u64);
1117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         for (u64b = u64; u64b > 0; u64b--) {
1118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UChar u8 = get_UChar(c);
1119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            TRACE_D3("%x ", (UInt)u8);
1120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)(UWord)block;
1122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsMemSzB = (UWord)u64;
1123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_block2: {
1126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ULong  u64b;
1127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ULong  u64 = (ULong)get_UShort(c);
1128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UChar* block = get_address_of_Cursor(c);
1129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("%llu byte block: ", u64);
1130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         for (u64b = u64; u64b > 0; u64b--) {
1131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UChar u8 = get_UChar(c);
1132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            TRACE_D3("%x ", (UInt)u8);
1133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)(UWord)block;
1135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsMemSzB = (UWord)u64;
1136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_block4: {
1139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ULong  u64b;
1140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ULong  u64 = (ULong)get_UInt(c);
1141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UChar* block = get_address_of_Cursor(c);
1142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("%llu byte block: ", u64);
1143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         for (u64b = u64; u64b > 0; u64b--) {
1144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UChar u8 = get_UChar(c);
1145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            TRACE_D3("%x ", (UInt)u8);
1146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)(UWord)block;
1148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsMemSzB = (UWord)u64;
1149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_exprloc:
1152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_block: {
1153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ULong  u64b;
1154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ULong  u64 = (ULong)get_ULEB128(c);
1155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UChar* block = get_address_of_Cursor(c);
1156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("%llu byte block: ", u64);
1157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         for (u64b = u64; u64b > 0; u64b--) {
1158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UChar u8 = get_UChar(c);
1159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            TRACE_D3("%x ", (UInt)u8);
1160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)(UWord)block;
1162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsMemSzB = (UWord)u64;
1163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_ref_sig8: {
1166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ULong  u64b;
1167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UChar* block = get_address_of_Cursor(c);
1168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("8 byte signature: ");
1169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         for (u64b = 8; u64b > 0; u64b--) {
1170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UChar u8 = get_UChar(c);
1171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            TRACE_D3("%x ", (UInt)u8);
1172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *cts = (ULong)(UWord)block;
1174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         *ctsMemSzB = 8;
1175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
1176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case DW_FORM_indirect:
1178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         get_Form_contents (cts, ctsSzB, ctsMemSzB, cc, c, td3,
1179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            (DW_FORM)get_ULEB128(c));
1180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return;
1181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
1183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)(
1184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            "get_Form_contents: unhandled %d (%s) at <%lx>\n",
1185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            form, ML_(pp_DW_FORM)(form), get_position_of_Cursor(c));
1186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         c->barf("get_Form_contents: unhandled DW_FORM");
1187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
1192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
1193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Parsing of variable-related DIEs                     ---*/
1194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
1195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
1196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
1198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct _TempVar {
1199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar*  name; /* in DebugInfo's .strchunks */
1200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Represent ranges economically.  nRanges is the number of
1201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ranges.  Cases:
1202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         0: .rngOneMin .rngOneMax .manyRanges are all zero
1203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         1: .rngOneMin .rngOneMax hold the range; .rngMany is NULL
1204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         2: .rngOneMin .rngOneMax are zero; .rngMany holds the ranges.
1205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         This is merely an optimisation to avoid having to allocate
1206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         and free the XArray in the common (98%) of cases where there
1207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         is zero or one address ranges. */
1208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord   nRanges;
1209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr    rngOneMin;
1210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr    rngOneMax;
1211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      XArray* rngMany; /* of AddrRange.  NON-UNIQUE PTR in AR_DINFO. */
1212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Do not free .rngMany, since many TempVars will have the same
1213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         value.  Instead the associated storage is to be freed by
1214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         deleting 'rangetree', which stores a single copy of each
1215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         range. */
1216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* --- */
1217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int     level;
1218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord   typeR; /* a cuOff */
1219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      GExpr*  gexpr; /* for this variable */
1220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      GExpr*  fbGX;  /* to find the frame base of the enclosing fn, if
1221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        any */
1222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar*  fName; /* declaring file name, or NULL */
1223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int     fLine; /* declaring file line number, or zero */
1224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* offset in .debug_info, so that abstract instances can be
1225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         found to satisfy references from concrete instances. */
1226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord   dioff;
1227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord   absOri; /* so the absOri fields refer to dioff fields
1228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         in some other, related TempVar. */
1229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TempVar;
1231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define N_D3_VAR_STACK 48
1233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
1235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
1236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Contains the range stack: a stack of address ranges, one
1237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         stack entry for each nested scope.
1238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Some scope entries are created by function definitions
1240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (DW_AT_subprogram), and for those, we also note the GExpr
1241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         derived from its DW_AT_frame_base attribute, if any.
1242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Consequently it should be possible to find, for any
1243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         variable's DIE, the GExpr for the the containing function's
1244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_AT_frame_base by scanning back through the stack to find
1245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         the nearest entry associated with a function.  This somewhat
1246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         elaborate scheme is provided so as to make it possible to
1247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         obtain the correct DW_AT_frame_base expression even in the
1248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         presence of nested functions (or to be more precise, in the
1249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         presence of nested DW_AT_subprogram DIEs).
1250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
1251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int     sp; /* [sp] is innermost active entry; sp==-1 for empty
1252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     stack */
1253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      XArray* ranges[N_D3_VAR_STACK]; /* XArray of AddrRange */
1254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int     level[N_D3_VAR_STACK];  /* D3 DIE levels */
1255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool    isFunc[N_D3_VAR_STACK]; /* from DW_AT_subprogram? */
1256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      GExpr*  fbGX[N_D3_VAR_STACK];   /* if isFunc, contains the FB
1257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                         expr, else NULL */
1258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* The file name table.  Is a mapping from integer index to the
1259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (permanent) copy of the string, iow a non-img area. */
1260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      XArray* /* of UChar* */ filenameTable;
1261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   D3VarParser;
1263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void varstack_show ( D3VarParser* parser, HChar* str ) {
1265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Word i, j;
1266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("  varstack (%s) {\n", str);
1267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i <= parser->sp; i++) {
1268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      XArray* xa = parser->ranges[i];
1269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(xa);
1270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("    [%ld] (level %d)", i, parser->level[i]);
1271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (parser->isFunc[i]) {
1272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)(" (fbGX=%p)", parser->fbGX[i]);
1273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
1274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(parser->fbGX[i] == NULL);
1275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)(": ");
1277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (VG_(sizeXA)( xa ) == 0) {
1278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("** empty PC range array **");
1279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
1280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         for (j = 0; j < VG_(sizeXA)( xa ); j++) {
1281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            AddrRange* range = (AddrRange*) VG_(indexXA)( xa, j );
1282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vg_assert(range);
1283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_(printf)("[%#lx,%#lx] ", range->aMin, range->aMax);
1284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("\n");
1287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("  }\n");
1289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Remove from the stack, all entries with .level > 'level' */
1292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic
1293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid varstack_preen ( D3VarParser* parser, Bool td3, Int level )
1294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool changed = False;
1296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(parser->sp < N_D3_VAR_STACK);
1297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (True) {
1298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(parser->sp >= -1);
1299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (parser->sp == -1) break;
1300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (parser->level[parser->sp] <= level) break;
1301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (0)
1302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("BBBBAAAA varstack_pop [newsp=%d]\n", parser->sp-1);
1303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(parser->ranges[parser->sp]);
1304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Who allocated this xa?  get_range_list() or
1305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         unitary_range_list(). */
1306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(deleteXA)( parser->ranges[parser->sp] );
1307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      parser->ranges[parser->sp] = NULL;
1308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      parser->level[parser->sp]  = 0;
1309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      parser->isFunc[parser->sp] = False;
1310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      parser->fbGX[parser->sp]   = NULL;
1311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      parser->sp--;
1312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      changed = True;
1313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (changed && td3)
1315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      varstack_show( parser, "after preen" );
1316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void varstack_push ( CUConst* cc,
1319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            D3VarParser* parser,
1320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            Bool td3,
1321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            XArray* ranges, Int level,
1322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            Bool    isFunc, GExpr* fbGX ) {
1323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0)
1324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_D3("BBBBAAAA varstack_push[newsp=%d]: %d  %p\n",
1325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            parser->sp+1, level, ranges);
1326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* First we need to zap everything >= 'level', as we are about to
1328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      replace any previous entry at 'level', so .. */
1329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   varstack_preen(parser, /*td3*/False, level-1);
1330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(parser->sp >= -1);
1332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(parser->sp < N_D3_VAR_STACK);
1333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (parser->sp == N_D3_VAR_STACK-1)
1334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc->barf("varstack_push: N_D3_VAR_STACK is too low; "
1335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               "increase and recompile");
1336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (parser->sp >= 0)
1337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(parser->level[parser->sp] < level);
1338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   parser->sp++;
1339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(parser->ranges[parser->sp] == NULL);
1340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(parser->level[parser->sp]  == 0);
1341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(parser->isFunc[parser->sp] == False);
1342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(parser->fbGX[parser->sp]   == NULL);
1343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(ranges != NULL);
1344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!isFunc) vg_assert(fbGX == NULL);
1345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   parser->ranges[parser->sp] = ranges;
1346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   parser->level[parser->sp]  = level;
1347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   parser->isFunc[parser->sp] = isFunc;
1348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   parser->fbGX[parser->sp]   = fbGX;
1349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (td3)
1350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      varstack_show( parser, "after push" );
1351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* cts, ctsSzB, ctsMemSzB are derived from a DW_AT_location and so
1355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   refer either to a location expression or to a location list.
1356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Figure out which, and in both cases bundle the expression or
1357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   location list into a so-called GExpr (guarded expression). */
1358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline))
1359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic GExpr* get_GX ( CUConst* cc, Bool td3,
1360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       ULong cts, Int ctsSzB, UWord ctsMemSzB )
1361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GExpr* gexpr = NULL;
1363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ctsMemSzB > 0 && ctsSzB == 0) {
1364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* represents an in-line location expression, and cts points
1365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         right at it */
1366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      gexpr = make_singleton_GX( (UChar*)(UWord)cts, ctsMemSzB );
1367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   else
1369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ctsMemSzB == 0 && ctsSzB > 0) {
1370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* represents location list.  cts is the offset of it in
1371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         .debug_loc. */
1372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!cc->cu_svma_known)
1373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         cc->barf("get_GX: location list, but CU svma is unknown");
1374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      gexpr = make_general_GX( cc, td3, (UWord)cts, cc->cu_svma );
1375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   else {
1377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(0); /* else caller is bogus */
1378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return gexpr;
1380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic
1384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid read_filename_table( /*MOD*/D3VarParser* parser,
1385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          CUConst* cc, UWord debug_line_offset,
1386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          Bool td3 )
1387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool   is_dw64;
1389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Cursor c;
1390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Word   i;
1391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UShort version;
1392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar  opcode_base;
1393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar* str;
1394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(parser && cc && cc->barf);
1396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if ((!cc->debug_line_img)
1397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       || cc->debug_line_sz <= debug_line_offset)
1398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc->barf("read_filename_table: .debug_line is missing?");
1399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   init_Cursor( &c, cc->debug_line_img,
1401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                cc->debug_line_sz, debug_line_offset, cc->barf,
1402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                "Overrun whilst reading .debug_line section(1)" );
1403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* unit_length = */
1405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      get_Initial_Length( &is_dw64, &c,
1406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           "read_filename_table: invalid initial-length field" );
1407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   version = get_UShort( &c );
1408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (version != 2 && version != 3 && version != 4)
1409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     cc->barf("read_filename_table: Only DWARF version 2, 3 and 4 line info "
1410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              "is currently supported.");
1411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*header_length              = (ULong)*/ get_Dwarfish_UWord( &c, is_dw64 );
1412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*minimum_instruction_length = */ get_UChar( &c );
1413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (version >= 4)
1414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /*maximum_operations_per_insn = */ get_UChar( &c );
1415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*default_is_stmt            = */ get_UChar( &c );
1416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*line_base                  = (Char)*/ get_UChar( &c );
1417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*line_range                 = */ get_UChar( &c );
1418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   opcode_base                = get_UChar( &c );
1419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* skip over "standard_opcode_lengths" */
1420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 1; i < (Word)opcode_base; i++)
1421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     (void)get_UChar( &c );
1422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* skip over the directory names table */
1424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (peek_UChar(&c) != 0) {
1425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     (void)get_AsciiZ(&c);
1426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (void)get_UChar(&c); /* skip terminating zero */
1428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Read and record the file names table */
1430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(parser->filenameTable);
1431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert( VG_(sizeXA)( parser->filenameTable ) == 0 );
1432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Add a dummy index-zero entry.  DWARF3 numbers its files
1433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      from 1, for some reason. */
1434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   str = ML_(addStr)( cc->di, "<unknown_file>", -1 );
1435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(addToXA)( parser->filenameTable, &str );
1436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (peek_UChar(&c) != 0) {
1437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      str = get_AsciiZ(&c);
1438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("  read_filename_table: %ld %s\n",
1439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               VG_(sizeXA)(parser->filenameTable), str);
1440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      str = ML_(addStr)( cc->di, str, -1 );
1441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(addToXA)( parser->filenameTable, &str );
1442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (void)get_ULEB128( &c ); /* skip directory index # */
1443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (void)get_ULEB128( &c ); /* skip last mod time */
1444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (void)get_ULEB128( &c ); /* file size */
1445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* We're done!  The rest of it is not interesting. */
1447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline))
1451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void parse_var_DIE (
1452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*MOD*/WordFM* /* of (XArray* of AddrRange, void) */ rangestree,
1453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*MOD*/XArray* /* of TempVar* */ tempvars,
1454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*MOD*/XArray* /* of GExpr* */ gexprs,
1455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*MOD*/D3VarParser* parser,
1456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DW_TAG dtag,
1457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord posn,
1458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int level,
1459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Cursor* c_die,
1460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Cursor* c_abbv,
1461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   CUConst* cc,
1462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool td3
1463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown)
1464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ULong       cts;
1466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int         ctsSzB;
1467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord       ctsMemSzB;
1468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord saved_die_c_offset  = get_position_of_Cursor( c_die );
1470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord saved_abbv_c_offset = get_position_of_Cursor( c_abbv );
1471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   varstack_preen( parser, td3, level-1 );
1473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (dtag == DW_TAG_compile_unit) {
1475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool have_lo    = False;
1476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool have_hi1   = False;
1477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool have_range = False;
1478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr ip_lo    = 0;
1479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr ip_hi1   = 0;
1480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr rangeoff = 0;
1481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (True) {
1482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
1483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
1484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == 0 && form == 0) break;
1485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
1486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            cc, c_die, False/*td3*/, form );
1487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_low_pc && ctsSzB > 0) {
1488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ip_lo   = cts;
1489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            have_lo = True;
1490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_high_pc && ctsSzB > 0) {
1492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ip_hi1   = cts;
1493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            have_hi1 = True;
1494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_ranges && ctsSzB > 0) {
1496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            rangeoff = cts;
1497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            have_range = True;
1498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_stmt_list && ctsSzB > 0) {
1500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            read_filename_table( parser, cc, (UWord)cts, td3 );
1501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Now, does this give us an opportunity to find this
1504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         CU's svma? */
1505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0
1506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (level == 0 && have_lo) {
1507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(!cc->cu_svma_known); /* if this fails, it must be
1508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         because we've already seen a DW_TAG_compile_unit DIE at level
1509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         0.  But that can't happen, because DWARF3 only allows exactly
1510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         one top level DIE per CU. */
1511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         cc->cu_svma_known = True;
1512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         cc->cu_svma = ip_lo;
1513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (1)
1514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            TRACE_D3("BBBBAAAA acquire CU_SVMA of %p\n", cc->cu_svma);
1515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Now, it may be that this DIE doesn't tell us the CU's
1516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            SVMA, by way of not having a DW_AT_low_pc.  That's OK --
1517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            the CU doesn't *have* to have its SVMA specified.
1518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            But as per last para D3 spec sec 3.1.1 ("Normal and
1520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Partial Compilation Unit Entries", "If the base address
1521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            (viz, the SVMA) is undefined, then any DWARF entry of
1522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            structure defined interms of the base address of that
1523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            compilation unit is not valid.".  So that means, if whilst
1524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            processing the children of this top level DIE (or their
1525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            children, etc) we see a DW_AT_range, and cu_svma_known is
1526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            False, then the DIE that contains it is (per the spec)
1527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            invalid, and we can legitimately stop and complain. */
1528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
1530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* .. whereas The Reality is, simply assume the SVMA is zero
1531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if it isn't specified. */
1532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (level == 0) {
1533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(!cc->cu_svma_known);
1534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         cc->cu_svma_known = True;
1535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (have_lo)
1536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            cc->cu_svma = ip_lo;
1537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         else
1538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            cc->cu_svma = 0;
1539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
1541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Do we have something that looks sane? */
1542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (have_lo && have_hi1 && (!have_range)) {
1543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (ip_lo < ip_hi1)
1544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            varstack_push( cc, parser, td3,
1545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           unitary_range_list(ip_lo, ip_hi1 - 1),
1546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           level,
1547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           False/*isFunc*/, NULL/*fbGX*/ );
1548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else
1549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((!have_lo) && (!have_hi1) && have_range) {
1550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         varstack_push( cc, parser, td3,
1551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        get_range_list( cc, td3,
1552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                        rangeoff, cc->cu_svma ),
1553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        level,
1554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        False/*isFunc*/, NULL/*fbGX*/ );
1555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else
1556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((!have_lo) && (!have_hi1) && (!have_range)) {
1557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* CU has no code, presumably? */
1558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         varstack_push( cc, parser, td3,
1559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        empty_range_list(),
1560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        level,
1561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        False/*isFunc*/, NULL/*fbGX*/ );
1562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else
1563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (have_lo && (!have_hi1) && have_range && ip_lo == 0) {
1564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* broken DIE created by gcc-4.3.X ?  Ignore the
1565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            apparently-redundant DW_AT_low_pc and use the DW_AT_ranges
1566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            instead. */
1567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         varstack_push( cc, parser, td3,
1568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        get_range_list( cc, td3,
1569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                        rangeoff, cc->cu_svma ),
1570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        level,
1571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        False/*isFunc*/, NULL/*fbGX*/ );
1572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
1573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (0) VG_(printf)("I got hlo %d hhi1 %d hrange %d\n",
1574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            (Int)have_lo, (Int)have_hi1, (Int)have_range);
1575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto bad_DIE;
1576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (dtag == DW_TAG_lexical_block || dtag == DW_TAG_subprogram) {
1580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool   have_lo    = False;
1581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool   have_hi1   = False;
1582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool   have_range = False;
1583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr   ip_lo      = 0;
1584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr   ip_hi1     = 0;
1585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr   rangeoff   = 0;
1586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool   isFunc     = dtag == DW_TAG_subprogram;
1587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      GExpr* fbGX       = NULL;
1588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (True) {
1589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
1590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
1591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == 0 && form == 0) break;
1592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
1593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            cc, c_die, False/*td3*/, form );
1594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_low_pc && ctsSzB > 0) {
1595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ip_lo   = cts;
1596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            have_lo = True;
1597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_high_pc && ctsSzB > 0) {
1599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ip_hi1   = cts;
1600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            have_hi1 = True;
1601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_ranges && ctsSzB > 0) {
1603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            rangeoff = cts;
1604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            have_range = True;
1605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (isFunc
1607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             && attr == DW_AT_frame_base
1608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             && ((ctsMemSzB > 0 && ctsSzB == 0)
1609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 || (ctsMemSzB == 0 && ctsSzB > 0))) {
1610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            fbGX = get_GX( cc, False/*td3*/, cts, ctsSzB, ctsMemSzB );
1611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vg_assert(fbGX);
1612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_(addToXA)(gexprs, &fbGX);
1613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Do we have something that looks sane? */
1616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (dtag == DW_TAG_subprogram
1617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          && (!have_lo) && (!have_hi1) && (!have_range)) {
1618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* This is legit - ignore it. Sec 3.3.3: "A subroutine entry
1619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            representing a subroutine declaration that is not also a
1620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            definition does not have code address or range
1621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            attributes." */
1622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else
1623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (dtag == DW_TAG_lexical_block
1624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          && (!have_lo) && (!have_hi1) && (!have_range)) {
1625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* I believe this is legit, and means the lexical block
1626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            contains no insns (whatever that might mean).  Ignore. */
1627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else
1628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (have_lo && have_hi1 && (!have_range)) {
1629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* This scope supplies just a single address range. */
1630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (ip_lo < ip_hi1)
1631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            varstack_push( cc, parser, td3,
1632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           unitary_range_list(ip_lo, ip_hi1 - 1),
1633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           level, isFunc, fbGX );
1634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else
1635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((!have_lo) && (!have_hi1) && have_range) {
1636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* This scope supplies multiple address ranges via the use of
1637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            a range list. */
1638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         varstack_push( cc, parser, td3,
1639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        get_range_list( cc, td3,
1640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                        rangeoff, cc->cu_svma ),
1641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        level, isFunc, fbGX );
1642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else
1643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (have_lo && (!have_hi1) && (!have_range)) {
1644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* This scope is bogus.  The D3 spec sec 3.4 (Lexical Block
1645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Entries) says fairly clearly that a scope must have either
1646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            _range or (_low_pc and _high_pc). */
1647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* The spec is a bit ambiguous though.  Perhaps a single byte
1648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            range is intended?  See sec 2.17 (Code Addresses And Ranges) */
1649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* This case is here because icc9 produced this:
1650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         <2><13bd>: DW_TAG_lexical_block
1651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            DW_AT_decl_line   : 5229
1652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            DW_AT_decl_column : 37
1653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            DW_AT_decl_file   : 1
1654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            DW_AT_low_pc      : 0x401b03
1655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         */
1656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Ignore (seems safe than pushing a single byte range) */
1657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else
1658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto bad_DIE;
1659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (dtag == DW_TAG_variable || dtag == DW_TAG_formal_parameter) {
1662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar* name        = NULL;
1663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord  typeR       = D3_INVALID_CUOFF;
1664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool   external    = False;
1665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      GExpr* gexpr       = NULL;
1666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int    n_attrs     = 0;
1667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord  abs_ori     = (UWord)D3_INVALID_CUOFF;
1668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int    lineNo      = 0;
1669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar* fileName    = NULL;
1670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (True) {
1671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
1672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
1673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == 0 && form == 0) break;
1674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
1675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            cc, c_die, False/*td3*/, form );
1676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         n_attrs++;
1677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_name && ctsMemSzB > 0) {
1678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            name = ML_(addStr)( cc->di, (UChar*)(UWord)cts, -1 );
1679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_location
1681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             && ((ctsMemSzB > 0 && ctsSzB == 0)
1682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 || (ctsMemSzB == 0 && ctsSzB > 0))) {
1683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            gexpr = get_GX( cc, False/*td3*/, cts, ctsSzB, ctsMemSzB );
1684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vg_assert(gexpr);
1685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_(addToXA)(gexprs, &gexpr);
1686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_type && ctsSzB > 0) {
1688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            typeR = (UWord)cts;
1689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_external && ctsSzB > 0 && cts > 0) {
1691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            external = True;
1692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_abstract_origin && ctsSzB > 0) {
1694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            abs_ori = (UWord)cts;
1695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_declaration && ctsSzB > 0 && cts > 0) {
1697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            /*declaration = True;*/
1698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_decl_line && ctsSzB > 0) {
1700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            lineNo = (Int)cts;
1701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_decl_file && ctsSzB > 0) {
1703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Int ftabIx = (Int)cts;
1704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (ftabIx >= 1
1705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                && ftabIx < VG_(sizeXA)( parser->filenameTable )) {
1706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               fileName = *(UChar**)
1707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          VG_(indexXA)( parser->filenameTable, ftabIx );
1708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               vg_assert(fileName);
1709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
1710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (0) VG_(printf)("XXX filename = %s\n", fileName);
1711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* We'll collect it under if one of the following three
1714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         conditions holds:
1715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (1) has location and type    -> completed
1716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (2) has type only            -> is an abstract instance
1717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (3) has location and abs_ori -> is a concrete instance
1718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Name, filename and line number are all optional frills.
1719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      */
1720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ( /* 1 */ (gexpr && typeR != D3_INVALID_CUOFF)
1721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           /* 2 */ || (typeR != D3_INVALID_CUOFF)
1722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           /* 3 */ || (gexpr && abs_ori != (UWord)D3_INVALID_CUOFF) ) {
1723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Add this variable to the list of interesting looking
1725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            variables.  Crucially, note along with it the address
1726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            range(s) associated with the variable, which for locals
1727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            will be the address ranges at the top of the varparser's
1728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            stack. */
1729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         GExpr*   fbGX = NULL;
1730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Word     i, nRanges;
1731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         XArray*  /* of AddrRange */ xa;
1732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TempVar* tv;
1733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Stack can't be empty; we put a dummy entry on it for the
1734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            entire address range before starting with the DIEs for
1735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            this CU. */
1736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(parser->sp >= 0);
1737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* If this is a local variable (non-external), try to find
1739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            the GExpr for the DW_AT_frame_base of the containing
1740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            function.  It should have been pushed on the stack at the
1741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            time we encountered its DW_TAG_subprogram DIE, so the way
1742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            to find it is to scan back down the stack looking for it.
1743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            If there isn't an enclosing stack entry marked 'isFunc'
1744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            then we must be seeing variable or formal param DIEs
1745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            outside of a function, so we deem the Dwarf to be
1746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            malformed if that happens.  Note that the fbGX may be NULL
1747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if the containing DT_TAG_subprogram didn't supply a
1748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            DW_AT_frame_base -- that's OK, but there must actually be
1749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            a containing DW_TAG_subprogram. */
1750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (!external) {
1751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Bool found = False;
1752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            for (i = parser->sp; i >= 0; i--) {
1753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               if (parser->isFunc[i]) {
1754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  fbGX = parser->fbGX[i];
1755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  found = True;
1756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  break;
1757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               }
1758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
1759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (!found) {
1760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               if (0 && VG_(clo_verbosity) >= 0) {
1761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  VG_(message)(Vg_DebugMsg,
1762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "warning: parse_var_DIE: non-external variable "
1763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "outside DW_TAG_subprogram\n");
1764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               }
1765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               /* goto bad_DIE; */
1766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               /* This seems to happen a lot.  Just ignore it -- if,
1767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  when we come to evaluation of the location (guarded)
1768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  expression, it requires a frame base value, and
1769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  there's no expression for that, then evaluation as a
1770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  whole will fail.  Harmless - a bit of a waste of
1771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  cycles but nothing more. */
1772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
1773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* re "external ? 0 : parser->sp" (twice), if the var is
1776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            marked 'external' then we must put it at the global scope,
1777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            as only the global scope (level 0) covers the entire PC
1778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            address space.  It is asserted elsewhere that level 0
1779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            always covers the entire address space. */
1780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         xa = parser->ranges[external ? 0 : parser->sp];
1781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         nRanges = VG_(sizeXA)(xa);
1782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(nRanges >= 0);
1783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tv = ML_(dinfo_zalloc)( "di.readdwarf3.pvD.1", sizeof(TempVar) );
1785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tv->name   = name;
1786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tv->level  = external ? 0 : parser->sp;
1787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tv->typeR  = typeR;
1788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tv->gexpr  = gexpr;
1789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tv->fbGX   = fbGX;
1790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tv->fName  = fileName;
1791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tv->fLine  = lineNo;
1792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tv->dioff  = posn;
1793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tv->absOri = abs_ori;
1794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* See explanation on definition of type TempVar for the
1796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            reason for this elaboration. */
1797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tv->nRanges = nRanges;
1798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tv->rngOneMin = 0;
1799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tv->rngOneMax = 0;
1800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tv->rngMany = NULL;
1801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (nRanges == 1) {
1802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            AddrRange* range = VG_(indexXA)(xa, 0);
1803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            tv->rngOneMin = range->aMin;
1804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            tv->rngOneMax = range->aMax;
1805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         else if (nRanges > 1) {
1807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            /* See if we already have a range list which is
1808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               structurally identical.  If so, use that; if not, clone
1809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               this one, and add it to our collection. */
1810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UWord keyW, valW;
1811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (VG_(lookupFM)( rangestree, &keyW, &valW, (UWord)xa )) {
1812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               XArray* old = (XArray*)keyW;
1813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               tl_assert(valW == 0);
1814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               tl_assert(old != xa);
1815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               tv->rngMany = old;
1816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            } else {
1817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               XArray* cloned = VG_(cloneXA)( "di.readdwarf3.pvD.2", xa );
1818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               tv->rngMany = cloned;
1819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               VG_(addToFM)( rangestree, (UWord)cloned, 0 );
1820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
1821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(addToXA)( tempvars, &tv );
1824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("  Recording this variable, with %ld PC range(s)\n",
1826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  VG_(sizeXA)(xa) );
1827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* collect stats on how effective the ->ranges special
1828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            casing is */
1829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (0) {
1830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            static Int ntot=0, ngt=0;
1831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ntot++;
1832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (tv->rngMany) ngt++;
1833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (0 == (ntot % 100000))
1834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               VG_(printf)("XXXX %d tot, %d cloned\n", ntot, ngt);
1835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
1836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
1838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Here are some other weird cases seen in the wild:
1840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            We have a variable with a name and a type, but no
1842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            location.  I guess that's a sign that it has been
1843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            optimised away.  Ignore it.  Here's an example:
1844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            static Int lc_compar(void* n1, void* n2) {
1846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               MC_Chunk* mc1 = *(MC_Chunk**)n1;
1847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               MC_Chunk* mc2 = *(MC_Chunk**)n2;
1848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               return (mc1->data < mc2->data ? -1 : 1);
1849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
1850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Both mc1 and mc2 are like this
1852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            <2><5bc>: Abbrev Number: 21 (DW_TAG_variable)
1853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                DW_AT_name        : mc1
1854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                DW_AT_decl_file   : 1
1855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                DW_AT_decl_line   : 216
1856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                DW_AT_type        : <5d3>
1857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            whereas n1 and n2 do have locations specified.
1859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ---------------------------------------------
1861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            We see a DW_TAG_formal_parameter with a type, but
1863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            no name and no location.  It's probably part of a function type
1864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            construction, thusly, hence ignore it:
1865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         <1><2b4>: Abbrev Number: 12 (DW_TAG_subroutine_type)
1866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             DW_AT_sibling     : <2c9>
1867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             DW_AT_prototyped  : 1
1868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             DW_AT_type        : <114>
1869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         <2><2be>: Abbrev Number: 13 (DW_TAG_formal_parameter)
1870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             DW_AT_type        : <13e>
1871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         <2><2c3>: Abbrev Number: 13 (DW_TAG_formal_parameter)
1872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             DW_AT_type        : <133>
1873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ---------------------------------------------
1875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Is very minimal, like this:
1877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            <4><81d>: Abbrev Number: 44 (DW_TAG_variable)
1878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                DW_AT_abstract_origin: <7ba>
1879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            What that signifies I have no idea.  Ignore.
1880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ----------------------------------------------
1882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Is very minimal, like this:
1884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            <200f>: DW_TAG_formal_parameter
1885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                DW_AT_abstract_ori: <1f4c>
1886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                DW_AT_location    : 13440
1887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            What that signifies I have no idea.  Ignore.
1888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            It might be significant, though: the variable at least
1889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            has a location and so might exist somewhere.
1890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Maybe we should handle this.
1891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ---------------------------------------------
1893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            <22407>: DW_TAG_variable
1895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              DW_AT_name        : (indirect string, offset: 0x6579):
1896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                  vgPlain_trampoline_stuff_start
1897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              DW_AT_decl_file   : 29
1898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              DW_AT_decl_line   : 56
1899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              DW_AT_external    : 1
1900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              DW_AT_declaration : 1
1901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Nameless and typeless variable that has a location?  Who
1903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            knows.  Not me.
1904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            <2><3d178>: Abbrev Number: 22 (DW_TAG_variable)
1905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 DW_AT_location    : 9 byte block: 3 c0 c7 13 38 0 0 0 0
1906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                     (DW_OP_addr: 3813c7c0)
1907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            No, really.  Check it out.  gcc is quite simply borked.
1909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            <3><168cc>: Abbrev Number: 141 (DW_TAG_variable)
1910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            // followed by no attributes, and the next DIE is a sibling,
1911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            // not a child
1912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            */
1913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return;
1915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  bad_DIE:
1917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   set_position_of_Cursor( c_die,  saved_die_c_offset );
1918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   set_position_of_Cursor( c_abbv, saved_abbv_c_offset );
1919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("\nparse_var_DIE: confused by:\n");
1920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)(" <%d><%lx>: %s\n", level, posn, ML_(pp_DW_TAG)( dtag ) );
1921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (True) {
1922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
1923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
1924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (attr == 0 && form == 0) break;
1925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("     %18s: ", ML_(pp_DW_AT)(attr));
1926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Get the form contents, so as to print them */
1927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
1928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         cc, c_die, True, form );
1929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("\t\n");
1930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("\n");
1932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   cc->barf("parse_var_DIE: confused by the above DIE");
1933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*NOTREACHED*/
1934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
1938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
1939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Parsing of type-related DIEs                         ---*/
1940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
1941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
1942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define N_D3_TYPE_STACK 16
1944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
1946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
1947f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root      /* What source language?  'A'=Ada83/95,
1948f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root                                'C'=C/C++,
1949f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root                                'F'=Fortran,
1950f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root                                '?'=other
1951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Established once per compilation unit. */
1952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar language;
1953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* A stack of types which are currently under construction */
1954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   sp; /* [sp] is innermost active entry; sp==-1 for empty
1955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   stack */
1956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Note that the TyEnts in qparentE are temporary copies of the
1957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ones accumulating in the main tyent array.  So it is not safe
1958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         to free up anything on them when popping them off the stack
1959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (iow, it isn't safe to use TyEnt__make_EMPTY on them).  Just
1960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         memset them to zero when done. */
1961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TyEnt qparentE[N_D3_TYPE_STACK]; /* parent TyEnts */
1962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   qlevel[N_D3_TYPE_STACK];
1963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   D3TypeParser;
1966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void typestack_show ( D3TypeParser* parser, HChar* str ) {
1968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Word i;
1969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("  typestack (%s) {\n", str);
1970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i <= parser->sp; i++) {
1971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("    [%ld] (level %d): ", i, parser->qlevel[i]);
1972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ML_(pp_TyEnt)( &parser->qparentE[i] );
1973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("\n");
1974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("  }\n");
1976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Remove from the stack, all entries with .level > 'level' */
1979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic
1980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid typestack_preen ( D3TypeParser* parser, Bool td3, Int level )
1981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool changed = False;
1983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(parser->sp < N_D3_TYPE_STACK);
1984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (True) {
1985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(parser->sp >= -1);
1986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (parser->sp == -1) break;
1987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (parser->qlevel[parser->sp] <= level) break;
1988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (0)
1989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("BBBBAAAA typestack_pop [newsp=%d]\n", parser->sp-1);
1990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
1991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(memset)(&parser->qparentE[parser->sp], 0, sizeof(TyEnt));
1992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      parser->qparentE[parser->sp].cuOff = D3_INVALID_CUOFF;
1993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      parser->qparentE[parser->sp].tag = Te_EMPTY;
1994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      parser->qlevel[parser->sp] = 0;
1995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      parser->sp--;
1996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      changed = True;
1997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
1998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (changed && td3)
1999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typestack_show( parser, "after preen" );
2000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool typestack_is_empty ( D3TypeParser* parser ) {
2003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(parser->sp >= -1 && parser->sp < N_D3_TYPE_STACK);
2004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return parser->sp == -1;
2005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void typestack_push ( CUConst* cc,
2008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             D3TypeParser* parser,
2009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             Bool td3,
2010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             TyEnt* parentE, Int level ) {
2011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0)
2012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_D3("BBBBAAAA typestack_push[newsp=%d]: %d  %05lx\n",
2013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            parser->sp+1, level, parentE->cuOff);
2014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* First we need to zap everything >= 'level', as we are about to
2016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      replace any previous entry at 'level', so .. */
2017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typestack_preen(parser, /*td3*/False, level-1);
2018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(parser->sp >= -1);
2020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(parser->sp < N_D3_TYPE_STACK);
2021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (parser->sp == N_D3_TYPE_STACK-1)
2022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc->barf("typestack_push: N_D3_TYPE_STACK is too low; "
2023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               "increase and recompile");
2024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (parser->sp >= 0)
2025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(parser->qlevel[parser->sp] < level);
2026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   parser->sp++;
2027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(parser->qparentE[parser->sp].tag == Te_EMPTY);
2028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(parser->qlevel[parser->sp]  == 0);
2029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(parentE);
2030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(ML_(TyEnt__is_type)(parentE));
2031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(parentE->cuOff != D3_INVALID_CUOFF);
2032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   parser->qparentE[parser->sp] = *parentE;
2033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   parser->qlevel[parser->sp]  = level;
2034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (td3)
2035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typestack_show( parser, "after push" );
2036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2038f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root/* True if the subrange type being parsed gives the bounds of an array. */
2039f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Rootstatic Bool subrange_type_denotes_array_bounds ( D3TypeParser* parser,
2040f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root                                                 DW_TAG dtag ) {
2041f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root   vg_assert(dtag == DW_TAG_subrange_type);
2042f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root   /* For most languages, a subrange_type dtag always gives the
2043f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root      bounds of an array.
2044f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root      For Ada, there are additional conditions as a subrange_type
2045f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root      is also used for other purposes. */
2046f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root   if (parser->language != 'A')
2047f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root      /* not Ada, so it definitely denotes an array bound. */
2048f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root      return True;
2049f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root   else
2050f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root      /* Extra constraints for Ada: it only denotes an array bound if .. */
2051f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root      return (! typestack_is_empty(parser)
2052f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root              && parser->qparentE[parser->sp].tag == Te_TyArray);
2053f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root}
2054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Parse a type-related DIE.  'parser' holds the current parser state.
2056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   'admin' is where the completed types are dumped.  'dtag' is the tag
2057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for this DIE.  'c_die' points to the start of the data fields (FORM
2058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   stuff) for the DIE.  c_abbv points to the start of the (name,form)
2059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pairs which describe the DIE.
2060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   We may find the DIE uninteresting, in which case we should ignore
2062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   it.
2063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   What happens: the DIE is examined.  If uninteresting, it is ignored.
2065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Otherwise, the DIE gives rise to two things:
2066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (1) the offset of this DIE in the CU -- the cuOffset, a UWord
2068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (2) a TyAdmin structure, which holds the type, or related stuff
2069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (2) is added at the end of 'tyadmins', at some index, say 'i'.
2071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   A pair (cuOffset, i) is added to 'tydict'.
2073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Hence 'tyadmins' holds the actual type entities, and 'tydict' holds
2075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   a mapping from cuOffset to the index of the corresponding entry in
2076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   'tyadmin'.
2077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   When resolving a cuOffset to a TyAdmin, first look up the cuOffset
2079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   in the tydict (by binary search).  This gives an index into
2080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tyadmins, and the required entity lives in tyadmins at that index.
2081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
2082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline))
2083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents,
2084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             /*MOD*/D3TypeParser* parser,
2085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             DW_TAG dtag,
2086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             UWord posn,
2087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             Int level,
2088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             Cursor* c_die,
2089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             Cursor* c_abbv,
2090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             CUConst* cc,
2091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             Bool td3 )
2092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ULong cts;
2094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int   ctsSzB;
2095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord ctsMemSzB;
2096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TyEnt typeE;
2097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TyEnt atomE;
2098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TyEnt fieldE;
2099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TyEnt boundE;
2100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord saved_die_c_offset  = get_position_of_Cursor( c_die );
2102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord saved_abbv_c_offset = get_position_of_Cursor( c_abbv );
2103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(memset)( &typeE,  0xAA, sizeof(typeE) );
2105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(memset)( &atomE,  0xAA, sizeof(atomE) );
2106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(memset)( &fieldE, 0xAA, sizeof(fieldE) );
2107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(memset)( &boundE, 0xAA, sizeof(boundE) );
2108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* If we've returned to a level at or above any previously noted
2110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      parent, un-note it, so we don't believe we're still collecting
2111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      its children. */
2112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typestack_preen( parser, td3, level-1 );
2113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (dtag == DW_TAG_compile_unit) {
2115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* See if we can find DW_AT_language, since it is important for
2116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         establishing array bounds (see DW_TAG_subrange_type below in
2117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         this fn) */
2118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (True) {
2119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == 0 && form == 0) break;
2122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
2123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            cc, c_die, False/*td3*/, form );
2124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr != DW_AT_language)
2125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            continue;
2126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (ctsSzB == 0)
2127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           goto bad_DIE;
2128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         switch (cts) {
2129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case DW_LANG_C89: case DW_LANG_C:
2130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case DW_LANG_C_plus_plus: case DW_LANG_ObjC:
2131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case DW_LANG_ObjC_plus_plus: case DW_LANG_UPC:
2132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case DW_LANG_Upc: case DW_LANG_C99:
2133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               parser->language = 'C'; break;
2134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case DW_LANG_Fortran77: case DW_LANG_Fortran90:
2135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case DW_LANG_Fortran95:
2136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               parser->language = 'F'; break;
2137f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root            case DW_LANG_Ada83: case DW_LANG_Ada95:
2138f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root               parser->language = 'A'; break;
2139f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root            case DW_LANG_Cobol74:
2140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case DW_LANG_Cobol85: case DW_LANG_Pascal83:
2141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case DW_LANG_Modula2: case DW_LANG_Java:
2142f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root            case DW_LANG_PLI:
2143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case DW_LANG_D: case DW_LANG_Python:
2144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            case DW_LANG_Mips_Assembler:
2145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               parser->language = '?'; break;
2146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            default:
2147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               goto bad_DIE;
2148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (dtag == DW_TAG_base_type) {
2153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* We can pick up a new base type any time. */
2154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(memset)(&typeE, 0, sizeof(typeE));
2155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.cuOff = D3_INVALID_CUOFF;
2156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.tag   = Te_TyBase;
2157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (True) {
2158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == 0 && form == 0) break;
2161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
2162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            cc, c_die, False/*td3*/, form );
2163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_name && ctsMemSzB > 0) {
2164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            typeE.Te.TyBase.name
2165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               = ML_(dinfo_strdup)( "di.readdwarf3.ptD.base_type.1",
2166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    (UChar*)(UWord)cts );
2167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_byte_size && ctsSzB > 0) {
2169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            typeE.Te.TyBase.szB = cts;
2170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_encoding && ctsSzB > 0) {
2172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            switch (cts) {
2173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               case DW_ATE_unsigned: case DW_ATE_unsigned_char:
2174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               case DW_ATE_UTF: /* since DWARF4, e.g. char16_t from C++ */
2175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               case DW_ATE_boolean:/* FIXME - is this correct? */
2176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  typeE.Te.TyBase.enc = 'U'; break;
2177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               case DW_ATE_signed: case DW_ATE_signed_char:
2178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  typeE.Te.TyBase.enc = 'S'; break;
2179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               case DW_ATE_float:
2180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  typeE.Te.TyBase.enc = 'F'; break;
2181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               case DW_ATE_complex_float:
2182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  typeE.Te.TyBase.enc = 'C'; break;
2183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               default:
2184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  goto bad_DIE;
2185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
2186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Invent a name if it doesn't have one.  gcc-4.3
2190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         -ftree-vectorize is observed to emit nameless base types. */
2191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!typeE.Te.TyBase.name)
2192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         typeE.Te.TyBase.name
2193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            = ML_(dinfo_strdup)( "di.readdwarf3.ptD.base_type.2",
2194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 "<anon_base_type>" );
2195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Do we have something that looks sane? */
2197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (/* must have a name */
2198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          typeE.Te.TyBase.name == NULL
2199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          /* and a plausible size.  Yes, really 32: "complex long
2200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             double" apparently has size=32 */
2201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          || typeE.Te.TyBase.szB < 0 || typeE.Te.TyBase.szB > 32
2202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          /* and a plausible encoding */
2203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          || (typeE.Te.TyBase.enc != 'U'
2204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              && typeE.Te.TyBase.enc != 'S'
2205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              && typeE.Te.TyBase.enc != 'F'
2206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              && typeE.Te.TyBase.enc != 'C'))
2207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto bad_DIE;
2208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Last minute hack: if we see this
2209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         <1><515>: DW_TAG_base_type
2210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             DW_AT_byte_size   : 0
2211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             DW_AT_encoding    : 5
2212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             DW_AT_name        : void
2213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         convert it into a real Void type. */
2214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (typeE.Te.TyBase.szB == 0
2215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          && 0 == VG_(strcmp)("void", typeE.Te.TyBase.name)) {
2216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ML_(TyEnt__make_EMPTY)(&typeE);
2217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         typeE.tag = Te_TyVoid;
2218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         typeE.Te.TyVoid.isFake = False; /* it's a real one! */
2219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      goto acquire_Type;
2222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (dtag == DW_TAG_pointer_type || dtag == DW_TAG_reference_type
2225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       || dtag == DW_TAG_ptr_to_member_type) {
2226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* This seems legit for _pointer_type and _reference_type.  I
2227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         don't know if rolling _ptr_to_member_type in here really is
2228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         legit, but it's better than not handling it at all. */
2229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(memset)(&typeE, 0, sizeof(typeE));
2230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.cuOff = D3_INVALID_CUOFF;
2231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.tag   = Te_TyPorR;
2232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* target type defaults to void */
2233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.Te.TyPorR.typeR = D3_FAKEVOID_CUOFF;
2234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.Te.TyPorR.isPtr = dtag == DW_TAG_pointer_type
2235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              || dtag == DW_TAG_ptr_to_member_type;
2236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* These three type kinds don't *have* to specify their size, in
2237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         which case we assume it's a machine word.  But if they do
2238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         specify it, it must be a machine word :-)  This probably
2239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         assumes that the word size of the Dwarf3 we're reading is the
2240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         same size as that on the machine.  gcc appears to give a size
2241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         whereas icc9 doesn't. */
2242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.Te.TyPorR.szB = sizeof(UWord);
2243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (True) {
2244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == 0 && form == 0) break;
2247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
2248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            cc, c_die, False/*td3*/, form );
2249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_byte_size && ctsSzB > 0) {
2250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            typeE.Te.TyPorR.szB = cts;
2251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_type && ctsSzB > 0) {
2253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            typeE.Te.TyPorR.typeR = (UWord)cts;
2254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Do we have something that looks sane? */
2257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (typeE.Te.TyPorR.szB != sizeof(UWord))
2258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto bad_DIE;
2259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
2260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto acquire_Type;
2261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (dtag == DW_TAG_enumeration_type) {
2264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Create a new Type to hold the results. */
2265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(memset)(&typeE, 0, sizeof(typeE));
2266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.cuOff = posn;
2267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.tag   = Te_TyEnum;
2268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.Te.TyEnum.atomRs
2269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ptD.enum_type.1",
2270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       ML_(dinfo_free),
2271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       sizeof(UWord) );
2272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (True) {
2273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == 0 && form == 0) break;
2276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
2277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            cc, c_die, False/*td3*/, form );
2278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_name && ctsMemSzB > 0) {
2279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            typeE.Te.TyEnum.name
2280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              = ML_(dinfo_strdup)( "di.readdwarf3.pTD.enum_type.2",
2281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   (UChar*)(UWord)cts );
2282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_byte_size && ctsSzB > 0) {
2284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            typeE.Te.TyEnum.szB = cts;
2285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!typeE.Te.TyEnum.name)
2289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         typeE.Te.TyEnum.name
2290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            = ML_(dinfo_strdup)( "di.readdwarf3.pTD.enum_type.3",
2291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 "<anon_enum_type>" );
2292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Do we have something that looks sane? */
2294f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root      if (typeE.Te.TyEnum.szB == 0
2295f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root          /* we must know the size */
2296f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root          /* but not for Ada, which uses such dummy
2297f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root             enumerations as helper for gdb ada mode. */
2298f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root          && parser->language != 'A')
2299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto bad_DIE;
2300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* On't stack! */
2301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typestack_push( cc, parser, td3, &typeE, level );
2302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      goto acquire_Type;
2303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* gcc (GCC) 4.4.0 20081017 (experimental) occasionally produces
2306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      DW_TAG_enumerator with only a DW_AT_name but no
2307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      DW_AT_const_value.  This is in violation of the Dwarf3 standard,
2308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      and appears to be a new "feature" of gcc - versions 4.3.x and
2309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      earlier do not appear to do this.  So accept DW_TAG_enumerator
2310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      which only have a name but no value.  An example:
2311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      <1><180>: Abbrev Number: 6 (DW_TAG_enumeration_type)
2313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         <181>   DW_AT_name        : (indirect string, offset: 0xda70):
2314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                     QtMsgType
2315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         <185>   DW_AT_byte_size   : 4
2316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         <186>   DW_AT_decl_file   : 14
2317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         <187>   DW_AT_decl_line   : 1480
2318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         <189>   DW_AT_sibling     : <0x1a7>
2319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      <2><18d>: Abbrev Number: 7 (DW_TAG_enumerator)
2320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         <18e>   DW_AT_name        : (indirect string, offset: 0x9e18):
2321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                     QtDebugMsg
2322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      <2><192>: Abbrev Number: 7 (DW_TAG_enumerator)
2323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         <193>   DW_AT_name        : (indirect string, offset: 0x1505f):
2324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                     QtWarningMsg
2325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      <2><197>: Abbrev Number: 7 (DW_TAG_enumerator)
2326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         <198>   DW_AT_name        : (indirect string, offset: 0x16f4a):
2327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                     QtCriticalMsg
2328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      <2><19c>: Abbrev Number: 7 (DW_TAG_enumerator)
2329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         <19d>   DW_AT_name        : (indirect string, offset: 0x156dd):
2330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                     QtFatalMsg
2331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      <2><1a1>: Abbrev Number: 7 (DW_TAG_enumerator)
2332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         <1a2>   DW_AT_name        : (indirect string, offset: 0x13660):
2333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                     QtSystemMsg
2334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   */
2335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (dtag == DW_TAG_enumerator) {
2336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(memset)( &atomE, 0, sizeof(atomE) );
2337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      atomE.cuOff = posn;
2338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      atomE.tag   = Te_Atom;
2339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (True) {
2340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == 0 && form == 0) break;
2343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
2344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            cc, c_die, False/*td3*/, form );
2345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_name && ctsMemSzB > 0) {
2346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            atomE.Te.Atom.name
2347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              = ML_(dinfo_strdup)( "di.readdwarf3.pTD.enumerator.1",
2348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   (UChar*)(UWord)cts );
2349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_const_value && ctsSzB > 0) {
2351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            atomE.Te.Atom.value = cts;
2352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            atomE.Te.Atom.valueKnown = True;
2353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Do we have something that looks sane? */
2356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (atomE.Te.Atom.name == NULL)
2357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto bad_DIE;
2358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Do we have a plausible parent? */
2359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (typestack_is_empty(parser)) goto bad_DIE;
2360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
2361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(parser->qparentE[parser->sp].cuOff != D3_INVALID_CUOFF);
2362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (level != parser->qlevel[parser->sp]+1) goto bad_DIE;
2363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (parser->qparentE[parser->sp].tag != Te_TyEnum) goto bad_DIE;
2364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Record this child in the parent */
2365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(parser->qparentE[parser->sp].Te.TyEnum.atomRs);
2366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(addToXA)( parser->qparentE[parser->sp].Te.TyEnum.atomRs,
2367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    &atomE );
2368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* And record the child itself */
2369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      goto acquire_Atom;
2370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Treat DW_TAG_class_type as if it was a DW_TAG_structure_type.  I
2373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      don't know if this is correct, but it at least makes this reader
2374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      usable for gcc-4.3 produced Dwarf3. */
2375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (dtag == DW_TAG_structure_type || dtag == DW_TAG_class_type
2376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown       || dtag == DW_TAG_union_type) {
2377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool have_szB = False;
2378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool is_decl  = False;
2379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool is_spec  = False;
2380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Create a new Type to hold the results. */
2381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(memset)(&typeE, 0, sizeof(typeE));
2382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.cuOff = posn;
2383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.tag   = Te_TyStOrUn;
2384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.Te.TyStOrUn.name = NULL;
2385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.Te.TyStOrUn.fieldRs
2386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.pTD.struct_type.1",
2387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       ML_(dinfo_free),
2388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       sizeof(UWord) );
2389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.Te.TyStOrUn.complete = True;
2390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.Te.TyStOrUn.isStruct = dtag == DW_TAG_structure_type
2391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   || dtag == DW_TAG_class_type;
2392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (True) {
2393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == 0 && form == 0) break;
2396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
2397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            cc, c_die, False/*td3*/, form );
2398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_name && ctsMemSzB > 0) {
2399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            typeE.Te.TyStOrUn.name
2400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               = ML_(dinfo_strdup)( "di.readdwarf3.ptD.struct_type.2",
2401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    (UChar*)(UWord)cts );
2402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_byte_size && ctsSzB >= 0) {
2404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            typeE.Te.TyStOrUn.szB = cts;
2405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            have_szB = True;
2406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_declaration && ctsSzB > 0 && cts > 0) {
2408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            is_decl = True;
2409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_specification && ctsSzB > 0 && cts > 0) {
2411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            is_spec = True;
2412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Do we have something that looks sane? */
2415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (is_decl && (!is_spec)) {
2416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* It's a DW_AT_declaration.  We require the name but
2417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            nothing else. */
2418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (typeE.Te.TyStOrUn.name == NULL)
2419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            goto bad_DIE;
2420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         typeE.Te.TyStOrUn.complete = False;
2421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* JRS 2009 Aug 10: <possible kludge>? */
2422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Push this tyent on the stack, even though it's incomplete.
2423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            It appears that gcc-4.4 on Fedora 11 will sometimes create
2424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            DW_TAG_member entries for it, and so we need to have a
2425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            plausible parent present in order for that to work.  See
2426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            #200029 comments 8 and 9. */
2427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         typestack_push( cc, parser, td3, &typeE, level );
2428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* </possible kludge> */
2429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto acquire_Type;
2430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if ((!is_decl) /* && (!is_spec) */) {
2432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* this is the common, ordinary case */
2433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if ((!have_szB) /* we must know the size */
2434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             /* But the name can be present, or not */)
2435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            goto bad_DIE;
2436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* On't stack! */
2437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         typestack_push( cc, parser, td3, &typeE, level );
2438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto acquire_Type;
2439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else {
2441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* don't know how to handle any other variants just now */
2442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto bad_DIE;
2443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (dtag == DW_TAG_member) {
2447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Acquire member entries for both DW_TAG_structure_type and
2448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_TAG_union_type.  They differ minorly, in that struct
2449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         members must have a DW_AT_data_member_location expression
2450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         whereas union members must not. */
2451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool parent_is_struct;
2452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(memset)( &fieldE, 0, sizeof(fieldE) );
2453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      fieldE.cuOff = posn;
2454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      fieldE.tag   = Te_Field;
2455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      fieldE.Te.Field.typeR = D3_INVALID_CUOFF;
2456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (True) {
2457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == 0 && form == 0) break;
2460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
2461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            cc, c_die, False/*td3*/, form );
2462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_name && ctsMemSzB > 0) {
2463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            fieldE.Te.Field.name
2464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               = ML_(dinfo_strdup)( "di.readdwarf3.ptD.member.1",
2465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    (UChar*)(UWord)cts );
2466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_type && ctsSzB > 0) {
2468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            fieldE.Te.Field.typeR = (UWord)cts;
2469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* There are 2 different cases for DW_AT_data_member_location.
2471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            If it is a constant class attribute, it contains byte offset
2472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            from the beginning of the containing entity.
2473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Otherwise it is a location expression.  */
2474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_data_member_location && ctsSzB > 0) {
2475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            fieldE.Te.Field.nLoc = -1;
2476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            fieldE.Te.Field.pos.offset = cts;
2477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else if (attr == DW_AT_data_member_location && ctsMemSzB > 0) {
2478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            fieldE.Te.Field.nLoc = (UWord)ctsMemSzB;
2479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            fieldE.Te.Field.pos.loc
2480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               = ML_(dinfo_memdup)( "di.readdwarf3.ptD.member.2",
2481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    (UChar*)(UWord)cts,
2482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    (SizeT)fieldE.Te.Field.nLoc );
2483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Do we have a plausible parent? */
2486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (typestack_is_empty(parser)) goto bad_DIE;
2487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
2488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(parser->qparentE[parser->sp].cuOff != D3_INVALID_CUOFF);
2489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (level != parser->qlevel[parser->sp]+1) goto bad_DIE;
2490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (parser->qparentE[parser->sp].tag != Te_TyStOrUn) goto bad_DIE;
2491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Do we have something that looks sane?  If this a member of a
2492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct, we must have a location expression; but if a member
2493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         of a union that is irrelevant (D3 spec sec 5.6.6).  We ought
2494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         to reject in the latter case, but some compilers have been
2495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         observed to emit constant-zero expressions.  So just ignore
2496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         them. */
2497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      parent_is_struct
2498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         = parser->qparentE[parser->sp].Te.TyStOrUn.isStruct;
2499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!fieldE.Te.Field.name)
2500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         fieldE.Te.Field.name
2501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            = ML_(dinfo_strdup)( "di.readdwarf3.ptD.member.3",
2502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 "<anon_field>" );
2503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(fieldE.Te.Field.name);
2504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (fieldE.Te.Field.typeR == D3_INVALID_CUOFF)
2505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto bad_DIE;
2506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (fieldE.Te.Field.nLoc) {
2507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (!parent_is_struct) {
2508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            /* If this is a union type, pretend we haven't seen the data
2509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               member location expression, as it is by definition
2510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               redundant (it must be zero). */
2511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (fieldE.Te.Field.nLoc > 0)
2512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               ML_(dinfo_free)(fieldE.Te.Field.pos.loc);
2513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            fieldE.Te.Field.pos.loc = NULL;
2514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            fieldE.Te.Field.nLoc = 0;
2515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Record this child in the parent */
2517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         fieldE.Te.Field.isStruct = parent_is_struct;
2518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(parser->qparentE[parser->sp].Te.TyStOrUn.fieldRs);
2519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(addToXA)( parser->qparentE[parser->sp].Te.TyStOrUn.fieldRs,
2520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       &posn );
2521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* And record the child itself */
2522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto acquire_Field;
2523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
2524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Member with no location - this can happen with static
2525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            const members in C++ code which are compile time constants
2526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            that do no exist in the class. They're not of any interest
2527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            to us so we ignore them. */
2528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (dtag == DW_TAG_array_type) {
2532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(memset)(&typeE, 0, sizeof(typeE));
2533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.cuOff = posn;
2534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.tag   = Te_TyArray;
2535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.Te.TyArray.typeR = D3_INVALID_CUOFF;
2536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.Te.TyArray.boundRs
2537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ptD.array_type.1",
2538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       ML_(dinfo_free),
2539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       sizeof(UWord) );
2540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (True) {
2541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == 0 && form == 0) break;
2544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
2545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            cc, c_die, False/*td3*/, form );
2546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_type && ctsSzB > 0) {
2547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            typeE.Te.TyArray.typeR = (UWord)cts;
2548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (typeE.Te.TyArray.typeR == D3_INVALID_CUOFF)
2551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto bad_DIE;
2552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* On't stack! */
2553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typestack_push( cc, parser, td3, &typeE, level );
2554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      goto acquire_Type;
2555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2557f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root   /* this is a subrange type defining the bounds of an array. */
2558f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root   if (dtag == DW_TAG_subrange_type
2559f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root       && subrange_type_denotes_array_bounds(parser, dtag)) {
2560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool have_lower = False;
2561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool have_upper = False;
2562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool have_count = False;
2563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Long lower = 0;
2564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Long upper = 0;
2565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      switch (parser->language) {
2567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         case 'C': have_lower = True;  lower = 0; break;
2568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         case 'F': have_lower = True;  lower = 1; break;
2569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         case '?': have_lower = False; break;
2570f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root         case 'A': have_lower = False; break;
2571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         default:  vg_assert(0); /* assured us by handling of
2572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    DW_TAG_compile_unit in this fn */
2573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(memset)( &boundE, 0, sizeof(boundE) );
2576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      boundE.cuOff = D3_INVALID_CUOFF;
2577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      boundE.tag   = Te_Bound;
2578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (True) {
2579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == 0 && form == 0) break;
2582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
2583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            cc, c_die, False/*td3*/, form );
2584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_lower_bound && ctsSzB > 0) {
2585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            lower      = (Long)cts;
2586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            have_lower = True;
2587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_upper_bound && ctsSzB > 0) {
2589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            upper      = (Long)cts;
2590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            have_upper = True;
2591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_count && ctsSzB > 0) {
2593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            /*count    = (Long)cts;*/
2594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            have_count = True;
2595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* FIXME: potentially skip the rest if no parent present, since
2598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         it could be the case that this subrange type is free-standing
2599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (not being used to describe the bounds of a containing array
2600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         type) */
2601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Do we have a plausible parent? */
2602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (typestack_is_empty(parser)) goto bad_DIE;
2603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
2604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(parser->qparentE[parser->sp].cuOff != D3_INVALID_CUOFF);
2605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (level != parser->qlevel[parser->sp]+1) goto bad_DIE;
2606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (parser->qparentE[parser->sp].tag != Te_TyArray) goto bad_DIE;
2607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Figure out if we have a definite range or not */
2609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (have_lower && have_upper && (!have_count)) {
2610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         boundE.Te.Bound.knownL = True;
2611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         boundE.Te.Bound.knownU = True;
2612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         boundE.Te.Bound.boundL = lower;
2613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         boundE.Te.Bound.boundU = upper;
2614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else if (have_lower && (!have_upper) && (!have_count)) {
2616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         boundE.Te.Bound.knownL = True;
2617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         boundE.Te.Bound.knownU = False;
2618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         boundE.Te.Bound.boundL = lower;
2619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         boundE.Te.Bound.boundU = 0;
2620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else if ((!have_lower) && have_upper && (!have_count)) {
2622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         boundE.Te.Bound.knownL = False;
2623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         boundE.Te.Bound.knownU = True;
2624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         boundE.Te.Bound.boundL = 0;
2625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         boundE.Te.Bound.boundU = upper;
2626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else if ((!have_lower) && (!have_upper) && (!have_count)) {
2628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         boundE.Te.Bound.knownL = False;
2629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         boundE.Te.Bound.knownU = False;
2630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         boundE.Te.Bound.boundL = 0;
2631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         boundE.Te.Bound.boundU = 0;
2632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
2633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* FIXME: handle more cases */
2634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto bad_DIE;
2635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Record this bound in the parent */
2638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      boundE.cuOff = posn;
2639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(parser->qparentE[parser->sp].Te.TyArray.boundRs);
2640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(addToXA)( parser->qparentE[parser->sp].Te.TyArray.boundRs,
2641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    &boundE );
2642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* And record the child itself */
2643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      goto acquire_Bound;
2644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2646f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root   /* typedef or subrange_type other than array bounds. */
2647f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root   if (dtag == DW_TAG_typedef
2648f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root       || (dtag == DW_TAG_subrange_type
2649f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root           && !subrange_type_denotes_array_bounds(parser, dtag))) {
2650f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root      /* subrange_type other than array bound is only for Ada. */
2651f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root      vg_assert (dtag == DW_TAG_typedef || parser->language == 'A');
2652f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root      /* We can pick up a new typedef/subrange_type any time. */
2653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(memset)(&typeE, 0, sizeof(typeE));
2654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.cuOff = D3_INVALID_CUOFF;
2655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.tag   = Te_TyTyDef;
2656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.Te.TyTyDef.name = NULL;
2657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.Te.TyTyDef.typeR = D3_INVALID_CUOFF;
2658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (True) {
2659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == 0 && form == 0) break;
2662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
2663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            cc, c_die, False/*td3*/, form );
2664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_name && ctsMemSzB > 0) {
2665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            typeE.Te.TyTyDef.name
2666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               = ML_(dinfo_strdup)( "di.readdwarf3.ptD.typedef.1",
2667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    (UChar*)(UWord)cts );
2668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_type && ctsSzB > 0) {
2670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            typeE.Te.TyTyDef.typeR = (UWord)cts;
2671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Do we have something that looks sane? */
2674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (/* must have a name */
2675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          typeE.Te.TyTyDef.name == NULL
2676f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root          /* However gcc gnat Ada generates minimal typedef
2677f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root             such as the below => accept no name for Ada.
2678f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root             <6><91cc>: DW_TAG_typedef
2679f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root                DW_AT_abstract_ori: <9066>
2680f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root          */
2681f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root          && parser->language != 'A'
2682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          /* but the referred-to type can be absent */)
2683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto bad_DIE;
2684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
2685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto acquire_Type;
2686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (dtag == DW_TAG_subroutine_type) {
2689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* function type? just record that one fact and ask no
2690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         further questions. */
2691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(memset)(&typeE, 0, sizeof(typeE));
2692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.cuOff = D3_INVALID_CUOFF;
2693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.tag   = Te_TyFn;
2694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      goto acquire_Type;
2695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (dtag == DW_TAG_volatile_type || dtag == DW_TAG_const_type) {
2698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int have_ty = 0;
2699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(memset)(&typeE, 0, sizeof(typeE));
2700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.cuOff = D3_INVALID_CUOFF;
2701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.tag   = Te_TyQual;
2702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.Te.TyQual.qual
2703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         = dtag == DW_TAG_volatile_type ? 'V' : 'C';
2704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* target type defaults to 'void' */
2705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typeE.Te.TyQual.typeR = D3_FAKEVOID_CUOFF;
2706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (True) {
2707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == 0 && form == 0) break;
2710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
2711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            cc, c_die, False/*td3*/, form );
2712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (attr == DW_AT_type && ctsSzB > 0) {
2713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            typeE.Te.TyQual.typeR = (UWord)cts;
2714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            have_ty++;
2715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
2716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* gcc sometimes generates DW_TAG_const/volatile_type without
2718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DW_AT_type and GDB appears to interpret the type as 'const
2719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         void' (resp. 'volatile void').  So just allow it .. */
2720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (have_ty == 1 || have_ty == 0)
2721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto acquire_Type;
2722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      else
2723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goto bad_DIE;
2724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* else ignore this DIE */
2727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return;
2728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*NOTREACHED*/
2729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  acquire_Type:
2731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0) VG_(printf)("YYYY Acquire Type\n");
2732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(ML_(TyEnt__is_type)( &typeE ));
2733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(typeE.cuOff == D3_INVALID_CUOFF || typeE.cuOff == posn);
2734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typeE.cuOff = posn;
2735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(addToXA)( tyents, &typeE );
2736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return;
2737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*NOTREACHED*/
2738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  acquire_Atom:
2740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0) VG_(printf)("YYYY Acquire Atom\n");
2741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(atomE.tag == Te_Atom);
2742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(atomE.cuOff == D3_INVALID_CUOFF || atomE.cuOff == posn);
2743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   atomE.cuOff = posn;
2744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(addToXA)( tyents, &atomE );
2745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return;
2746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*NOTREACHED*/
2747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  acquire_Field:
2749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* For union members, Expr should be absent */
2750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0) VG_(printf)("YYYY Acquire Field\n");
2751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(fieldE.tag == Te_Field);
2752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(fieldE.Te.Field.nLoc <= 0 || fieldE.Te.Field.pos.loc != NULL);
2753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(fieldE.Te.Field.nLoc != 0 || fieldE.Te.Field.pos.loc == NULL);
2754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (fieldE.Te.Field.isStruct) {
2755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(fieldE.Te.Field.nLoc != 0);
2756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
2757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(fieldE.Te.Field.nLoc == 0);
2758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(fieldE.cuOff == D3_INVALID_CUOFF || fieldE.cuOff == posn);
2760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   fieldE.cuOff = posn;
2761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(addToXA)( tyents, &fieldE );
2762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return;
2763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*NOTREACHED*/
2764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  acquire_Bound:
2766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0) VG_(printf)("YYYY Acquire Bound\n");
2767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(boundE.tag == Te_Bound);
2768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(boundE.cuOff == D3_INVALID_CUOFF || boundE.cuOff == posn);
2769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   boundE.cuOff = posn;
2770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(addToXA)( tyents, &boundE );
2771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return;
2772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*NOTREACHED*/
2773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  bad_DIE:
2775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   set_position_of_Cursor( c_die,  saved_die_c_offset );
2776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   set_position_of_Cursor( c_abbv, saved_abbv_c_offset );
2777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("\nparse_type_DIE: confused by:\n");
2778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)(" <%d><%lx>: %s\n", level, posn, ML_(pp_DW_TAG)( dtag ) );
2779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (True) {
2780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
2781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
2782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (attr == 0 && form == 0) break;
2783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("     %18s: ", ML_(pp_DW_AT)(attr));
2784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Get the form contents, so as to print them */
2785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
2786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         cc, c_die, True, form );
2787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("\t\n");
2788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(printf)("\n");
2790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   cc->barf("parse_type_DIE: confused by the above DIE");
2791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*NOTREACHED*/
2792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
2796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
2797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Compression of type DIE information                  ---*/
2798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
2799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
2800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UWord chase_cuOff ( Bool* changed,
2802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           XArray* /* of TyEnt */ ents,
2803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           TyEntIndexCache* ents_cache,
2804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           UWord cuOff )
2805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TyEnt* ent;
2807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache, cuOff );
2808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (!ent) {
2810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)("chase_cuOff: no entry for 0x%05lx\n", cuOff);
2811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *changed = False;
2812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return cuOff;
2813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(ent->tag != Te_EMPTY);
2816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (ent->tag != Te_INDIR) {
2817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *changed = False;
2818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return cuOff;
2819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
2820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(ent->Te.INDIR.indR < cuOff);
2821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *changed = True;
2822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      return ent->Te.INDIR.indR;
2823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic
2827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid chase_cuOffs_in_XArray ( Bool* changed,
2828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              XArray* /* of TyEnt */ ents,
2829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              TyEntIndexCache* ents_cache,
2830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                              /*MOD*/XArray* /* of UWord */ cuOffs )
2831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool b2 = False;
2833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Word i, n = VG_(sizeXA)( cuOffs );
2834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < n; i++) {
2835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool   b = False;
2836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord* p = VG_(indexXA)( cuOffs, i );
2837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      *p = chase_cuOff( &b, ents, ents_cache, *p );
2838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (b)
2839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         b2 = True;
2840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   *changed = b2;
2842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool TyEnt__subst_R_fields ( XArray* /* of TyEnt */ ents,
2845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    TyEntIndexCache* ents_cache,
2846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    /*MOD*/TyEnt* te )
2847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool b, changed = False;
2849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   switch (te->tag) {
2850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case Te_EMPTY:
2851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case Te_INDIR:
2853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         te->Te.INDIR.indR
2854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            = chase_cuOff( &b, ents, ents_cache, te->Te.INDIR.indR );
2855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (b) changed = True;
2856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case Te_UNKNOWN:
2858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case Te_Atom:
2860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case Te_Field:
2862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         te->Te.Field.typeR
2863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            = chase_cuOff( &b, ents, ents_cache, te->Te.Field.typeR );
2864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (b) changed = True;
2865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case Te_Bound:
2867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case Te_TyBase:
2869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case Te_TyPorR:
2871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         te->Te.TyPorR.typeR
2872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            = chase_cuOff( &b, ents, ents_cache, te->Te.TyPorR.typeR );
2873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (b) changed = True;
2874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case Te_TyTyDef:
2876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         te->Te.TyTyDef.typeR
2877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            = chase_cuOff( &b, ents, ents_cache, te->Te.TyTyDef.typeR );
2878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (b) changed = True;
2879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case Te_TyStOrUn:
2881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyStOrUn.fieldRs );
2882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (b) changed = True;
2883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case Te_TyEnum:
2885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyEnum.atomRs );
2886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (b) changed = True;
2887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case Te_TyArray:
2889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         te->Te.TyArray.typeR
2890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            = chase_cuOff( &b, ents, ents_cache, te->Te.TyArray.typeR );
2891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (b) changed = True;
2892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyArray.boundRs );
2893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (b) changed = True;
2894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case Te_TyFn:
2896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case Te_TyQual:
2898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         te->Te.TyQual.typeR
2899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            = chase_cuOff( &b, ents, ents_cache, te->Te.TyQual.typeR );
2900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (b) changed = True;
2901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      case Te_TyVoid:
2903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
2904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      default:
2905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ML_(pp_TyEnt)(te);
2906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(0);
2907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return changed;
2909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Make a pass over 'ents'.  For each tyent, inspect the target of any
2912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   'R' or 'Rs' fields (those which refer to other tyents), and replace
2913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   any which point to INDIR nodes with the target of the indirection
2914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   (which should not itself be an indirection).  In summary, this
2915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   routine shorts out all references to indirection nodes. */
2916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic
2917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownWord dedup_types_substitution_pass ( /*MOD*/XArray* /* of TyEnt */ ents,
2918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                     TyEntIndexCache* ents_cache )
2919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Word i, n, nChanged = 0;
2921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool b;
2922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n = VG_(sizeXA)( ents );
2923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < n; i++) {
2924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TyEnt* ent = VG_(indexXA)( ents, i );
2925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(ent->tag != Te_EMPTY);
2926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* We have to substitute everything, even indirections, so as to
2927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ensure that chains of indirections don't build up. */
2928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      b = TyEnt__subst_R_fields( ents, ents_cache, ent );
2929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (b)
2930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         nChanged++;
2931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return nChanged;
2934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Make a pass over 'ents', building a dictionary of TyEnts as we go.
2938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Look up each new tyent in the dictionary in turn.  If it is already
2939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   in the dictionary, replace this tyent with an indirection to the
2940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   existing one, and delete any malloc'd stuff hanging off this one.
2941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   In summary, this routine commons up all tyents that are identical
2942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   as defined by TyEnt__cmp_by_all_except_cuOff. */
2943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic
2944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownWord dedup_types_commoning_pass ( /*MOD*/XArray* /* of TyEnt */ ents )
2945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
2946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Word    n, i, nDeleted;
2947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   WordFM* dict; /* TyEnt* -> void */
2948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TyEnt*  ent;
2949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord   keyW, valW;
2950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   dict = VG_(newFM)(
2952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             ML_(dinfo_zalloc), "di.readdwarf3.dtcp.1",
2953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             ML_(dinfo_free),
2954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             (Word(*)(UWord,UWord)) ML_(TyEnt__cmp_by_all_except_cuOff)
2955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          );
2956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   nDeleted = 0;
2958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n = VG_(sizeXA)( ents );
2959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < n; i++) {
2960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ent = VG_(indexXA)( ents, i );
2961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(ent->tag != Te_EMPTY);
2962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Ignore indirections, although check that they are
2964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         not forming a cycle. */
2965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ent->tag == Te_INDIR) {
2966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(ent->Te.INDIR.indR < ent->cuOff);
2967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         continue;
2968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      keyW = valW = 0;
2971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (VG_(lookupFM)( dict, &keyW, &valW, (UWord)ent )) {
2972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* it's already in the dictionary. */
2973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TyEnt* old = (TyEnt*)keyW;
2974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(valW == 0);
2975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(old != ent);
2976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(old->tag != Te_INDIR);
2977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* since we are traversing the array in increasing order of
2978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            cuOff: */
2979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(old->cuOff < ent->cuOff);
2980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* So anyway, dump this entry and replace it with an
2981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            indirection to the one in the dictionary.  Note that the
2982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            assertion above guarantees that we cannot create cycles of
2983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            indirections, since we are always creating an indirection
2984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            to a tyent with a cuOff lower than this one. */
2985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ML_(TyEnt__make_EMPTY)( ent );
2986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ent->tag = Te_INDIR;
2987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ent->Te.INDIR.indR = old->cuOff;
2988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         nDeleted++;
2989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      } else {
2990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* not in dictionary; add it and keep going. */
2991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(addToFM)( dict, (UWord)ent, 0 );
2992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
2993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
2994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(deleteFM)( dict, NULL, NULL );
2996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return nDeleted;
2998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
2999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic
3002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid dedup_types ( Bool td3,
3003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   /*MOD*/XArray* /* of TyEnt */ ents,
3004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   TyEntIndexCache* ents_cache )
3005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Word m, n, i, nDel, nSubst, nThresh;
3007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (0) td3 = True;
3008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n = VG_(sizeXA)( ents );
3010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* If a commoning pass and a substitution pass both make fewer than
3012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      this many changes, just stop.  It's pointless to burn up CPU
3013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      time trying to compress the last 1% or so out of the array. */
3014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   nThresh = n / 200;
3015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* First we must sort .ents by its .cuOff fields, so we
3017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      can index into it. */
3018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(setCmpFnXA)(
3019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ents,
3020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (Int(*)(void*,void*)) ML_(TyEnt__cmp_by_cuOff_only)
3021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   );
3022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(sortXA)( ents );
3023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Now repeatedly do commoning and substitution passes over
3025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the array, until there are no more changes. */
3026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {
3027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      nDel   = dedup_types_commoning_pass ( ents );
3028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      nSubst = dedup_types_substitution_pass ( ents, ents_cache );
3029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(nDel >= 0 && nSubst >= 0);
3030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("   %ld deletions, %ld substitutions\n", nDel, nSubst);
3031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (nDel > nThresh || nSubst > nThresh);
3032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Sanity check: all INDIR nodes should point at a non-INDIR thing.
3034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      In fact this should be true at the end of every loop iteration
3035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      above (a commoning pass followed by a substitution pass), but
3036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      checking it on every iteration is excessively expensive.  Note,
3037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      this loop also computes 'm' for the stats printing below it. */
3038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   m = 0;
3039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n = VG_(sizeXA)( ents );
3040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < n; i++) {
3041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TyEnt *ent, *ind;
3042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ent = VG_(indexXA)( ents, i );
3043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ent->tag != Te_INDIR) continue;
3044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      m++;
3045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ind = ML_(TyEnts__index_by_cuOff)( ents, ents_cache,
3046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                         ent->Te.INDIR.indR );
3047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(ind);
3048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(ind->tag != Te_INDIR);
3049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_D3("Overall: %ld before, %ld after\n", n, n-m);
3052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
3056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
3057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Resolution of references to type DIEs                ---*/
3058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
3059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
3060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Make a pass through the (temporary) variables array.  Examine the
3062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   type of each variable, check is it found, and chase any Te_INDIRs.
3063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Postcondition is: each variable has a typeR field that refers to a
3064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   valid type in tyents, or a Te_UNKNOWN, and is certainly guaranteed
3065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   not to refer to a Te_INDIR.  (This is so that we can throw all the
3066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Te_INDIRs away later). */
3067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline))
3069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void resolve_variable_types (
3070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               void (*barf)( HChar* ) __attribute__((noreturn)),
3071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               /*R-O*/XArray* /* of TyEnt */ ents,
3072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               /*MOD*/TyEntIndexCache* ents_cache,
3073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               /*MOD*/XArray* /* of TempVar* */ vars
3074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            )
3075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Word i, n;
3077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n = VG_(sizeXA)( vars );
3078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < n; i++) {
3079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TempVar* var = *(TempVar**)VG_(indexXA)( vars, i );
3080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* This is the stated type of the variable.  But it might be
3081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         an indirection, so be careful. */
3082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TyEnt* ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache,
3083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                                var->typeR );
3084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ent && ent->tag == Te_INDIR) {
3085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache,
3086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                            ent->Te.INDIR.indR );
3087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(ent);
3088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(ent->tag != Te_INDIR);
3089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Deal first with "normal" cases */
3092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ent && ML_(TyEnt__is_type)(ent)) {
3093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         var->typeR = ent->cuOff;
3094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         continue;
3095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* If there's no ent, it probably we did not manage to read a
3098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         type at the cuOffset which is stated as being this variable's
3099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         type.  Maybe a deficiency in parse_type_DIE.  Complain. */
3100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ent == NULL) {
3101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("\n: Invalid cuOff = 0x%05lx\n", var->typeR );
3102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         barf("resolve_variable_types: "
3103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              "cuOff does not refer to a known type");
3104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(ent);
3106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* If ent has any other tag, something bad happened, along the
3107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         lines of var->typeR not referring to a type at all. */
3108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(ent->tag == Te_UNKNOWN);
3109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Just accept it; the type will be useless, but at least keep
3110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         going. */
3111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      var->typeR = ent->cuOff;
3112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
3117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
3118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Parsing of Compilation Units                         ---*/
3119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
3120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
3121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Int cmp_TempVar_by_dioff ( void* v1, void* v2 ) {
3123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TempVar* t1 = *(TempVar**)v1;
3124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TempVar* t2 = *(TempVar**)v2;
3125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (t1->dioff < t2->dioff) return -1;
3126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (t1->dioff > t2->dioff) return 1;
3127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return 0;
3128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void read_DIE (
3131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*MOD*/WordFM* /* of (XArray* of AddrRange, void) */ rangestree,
3132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*MOD*/XArray* /* of TyEnt */ tyents,
3133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*MOD*/XArray* /* of TempVar* */ tempvars,
3134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*MOD*/XArray* /* of GExpr* */ gexprs,
3135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*MOD*/D3TypeParser* typarser,
3136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*MOD*/D3VarParser* varparser,
3137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Cursor* c, Bool td3, CUConst* cc, Int level
3138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown)
3139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Cursor abbv;
3141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ULong  atag, abbv_code;
3142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord  posn;
3143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt   has_children;
3144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord  start_die_c_offset, start_abbv_c_offset;
3145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord  after_die_c_offset, after_abbv_c_offset;
3146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* --- Deal with this DIE --- */
3148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   posn      = get_position_of_Cursor( c );
3149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   abbv_code = get_ULEB128( c );
3150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   set_abbv_Cursor( &abbv, td3, cc, abbv_code );
3151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   atag      = get_ULEB128( &abbv );
3152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_D3("\n");
3153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_D3(" <%d><%lx>: Abbrev Number: %llu (%s)\n",
3154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            level, posn, abbv_code, ML_(pp_DW_TAG)( atag ) );
3155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (atag == 0)
3157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc->barf("read_DIE: invalid zero tag on DIE");
3158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   has_children = get_UChar( &abbv );
3160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (has_children != DW_children_no && has_children != DW_children_yes)
3161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc->barf("read_DIE: invalid has_children value");
3162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* We're set up to look at the fields of this DIE.  Hand it off to
3164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      any parser(s) that want to see it.  Since they will in general
3165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      advance both the DIE and abbrev cursors, remember their current
3166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      settings so that we can then back up and do one final pass over
3167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the DIE, to print out its contents. */
3168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   start_die_c_offset  = get_position_of_Cursor( c );
3170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   start_abbv_c_offset = get_position_of_Cursor( &abbv );
3171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (True) {
3173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ULong cts;
3174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   ctsSzB;
3175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord ctsMemSzB;
3176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ULong at_name = get_ULEB128( &abbv );
3177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ULong at_form = get_ULEB128( &abbv );
3178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (at_name == 0 && at_form == 0) break;
3179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("     %18s: ", ML_(pp_DW_AT)(at_name));
3180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Get the form contents, but ignore them; the only purpose is
3181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         to print them, if td3 is True */
3182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
3183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         cc, c, td3, (DW_FORM)at_form );
3184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("\t");
3185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("\n");
3186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   after_die_c_offset  = get_position_of_Cursor( c );
3189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   after_abbv_c_offset = get_position_of_Cursor( &abbv );
3190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   set_position_of_Cursor( c,     start_die_c_offset );
3192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   set_position_of_Cursor( &abbv, start_abbv_c_offset );
3193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   parse_type_DIE( tyents,
3195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   typarser,
3196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   (DW_TAG)atag,
3197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   posn,
3198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   level,
3199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   c,     /* DIE cursor */
3200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   &abbv, /* abbrev cursor */
3201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   cc,
3202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   td3 );
3203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   set_position_of_Cursor( c,     start_die_c_offset );
3205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   set_position_of_Cursor( &abbv, start_abbv_c_offset );
3206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   parse_var_DIE( rangestree,
3208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  tempvars,
3209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  gexprs,
3210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  varparser,
3211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  (DW_TAG)atag,
3212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  posn,
3213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  level,
3214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  c,     /* DIE cursor */
3215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  &abbv, /* abbrev cursor */
3216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  cc,
3217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  td3 );
3218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   set_position_of_Cursor( c,     after_die_c_offset );
3220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   set_position_of_Cursor( &abbv, after_abbv_c_offset );
3221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* --- Now recurse into its children, if any --- */
3223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (has_children == DW_children_yes) {
3224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (0) TRACE_D3("BEGIN children of level %d\n", level);
3225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (True) {
3226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         atag = peek_ULEB128( c );
3227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (atag == 0) break;
3228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         read_DIE( rangestree, tyents, tempvars, gexprs,
3229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   typarser, varparser,
3230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                   c, td3, cc, level+1 );
3231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Now we need to eat the terminating zero */
3233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      atag = get_ULEB128( c );
3234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(atag == 0);
3235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (0) TRACE_D3("END children of level %d\n", level);
3236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic
3242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid new_dwarf3_reader_wrk (
3243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct _DebugInfo* di,
3244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   __attribute__((noreturn)) void (*barf)( HChar* ),
3245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar* debug_info_img,   SizeT debug_info_sz,
3246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar* debug_abbv_img,   SizeT debug_abbv_sz,
3247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar* debug_line_img,   SizeT debug_line_sz,
3248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar* debug_str_img,    SizeT debug_str_sz,
3249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar* debug_ranges_img, SizeT debug_ranges_sz,
3250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar* debug_loc_img,    SizeT debug_loc_sz
3251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown)
3252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   XArray* /* of TyEnt */     tyents;
3254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   XArray* /* of TyEnt */     tyents_to_keep;
3255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   XArray* /* of GExpr* */    gexprs;
3256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   XArray* /* of TempVar* */  tempvars;
3257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   WordFM* /* of (XArray* of AddrRange, void) */ rangestree;
3258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TyEntIndexCache* tyents_cache = NULL;
3259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TyEntIndexCache* tyents_to_keep_cache = NULL;
3260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TempVar *varp, *varp2;
3261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   GExpr* gexpr;
3262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Cursor abbv; /* for showing .debug_abbrev */
3263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Cursor info; /* primary cursor for parsing .debug_info */
3264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Cursor ranges; /* for showing .debug_ranges */
3265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   D3TypeParser typarser;
3266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   D3VarParser varparser;
3267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr  dr_base;
3268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord dr_offset;
3269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Word  i, j, n;
3270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool td3 = di->trace_symtab;
3271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   XArray* /* of TempVar* */ dioff_lookup_tab;
3272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0
3273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* This doesn't work properly because it assumes all entries are
3274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      packed end to end, with no holes.  But that doesn't always
3275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      appear to be the case, so it loses sync.  And the D3 spec
3276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      doesn't appear to require a no-hole situation either. */
3277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Display .debug_loc */
3278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr  dl_base;
3279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord dl_offset;
3280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Cursor loc; /* for showing .debug_loc */
3281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_SYMTAB("\n");
3282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_SYMTAB("\n------ The contents of .debug_loc ------\n");
3283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_SYMTAB("    Offset   Begin    End      Expression\n");
3284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   init_Cursor( &loc, debug_loc_img,
3285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                debug_loc_sz, 0, barf,
3286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                "Overrun whilst reading .debug_loc section(1)" );
3287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   dl_base = 0;
3288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   dl_offset = 0;
3289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (True) {
3290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord  w1, w2;
3291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord  len;
3292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (is_at_end_Cursor( &loc ))
3293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
3294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Read a (host-)word pair.  This is something of a hack since
3296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         the word size to read is really dictated by the ELF file;
3297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         however, we assume we're reading a file with the same
3298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         word-sizeness as the host.  Reasonably enough. */
3299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      w1 = get_UWord( &loc );
3300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      w2 = get_UWord( &loc );
3301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (w1 == 0 && w2 == 0) {
3303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* end of list.  reset 'base' */
3304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("    %08lx <End of list>\n", dl_offset);
3305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         dl_base = 0;
3306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         dl_offset = get_position_of_Cursor( &loc );
3307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         continue;
3308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (w1 == -1UL) {
3311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* new value for 'base' */
3312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("    %08lx %16lx %08lx (base address)\n",
3313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  dl_offset, w1, w2);
3314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         dl_base = w2;
3315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         continue;
3316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* else a location expression follows */
3319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("    %08lx %08lx %08lx ",
3320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               dl_offset, w1 + dl_base, w2 + dl_base);
3321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      len = (UWord)get_UShort( &loc );
3322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (len > 0) {
3323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UChar byte = get_UChar( &loc );
3324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("%02x", (UInt)byte);
3325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         len--;
3326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_SYMTAB("\n");
3328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
3330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Display .debug_ranges */
3332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_SYMTAB("\n");
3333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_SYMTAB("\n------ The contents of .debug_ranges ------\n");
3334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_SYMTAB("    Offset   Begin    End\n");
3335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   init_Cursor( &ranges, debug_ranges_img,
3336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                debug_ranges_sz, 0, barf,
3337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                "Overrun whilst reading .debug_ranges section(1)" );
3338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   dr_base = 0;
3339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   dr_offset = 0;
3340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (True) {
3341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord  w1, w2;
3342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (is_at_end_Cursor( &ranges ))
3344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
3345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Read a (host-)word pair.  This is something of a hack since
3347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         the word size to read is really dictated by the ELF file;
3348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         however, we assume we're reading a file with the same
3349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         word-sizeness as the host.  Reasonably enough. */
3350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      w1 = get_UWord( &ranges );
3351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      w2 = get_UWord( &ranges );
3352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (w1 == 0 && w2 == 0) {
3354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* end of list.  reset 'base' */
3355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("    %08lx <End of list>\n", dr_offset);
3356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         dr_base = 0;
3357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         dr_offset = get_position_of_Cursor( &ranges );
3358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         continue;
3359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (w1 == -1UL) {
3362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* new value for 'base' */
3363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("    %08lx %16lx %08lx (base address)\n",
3364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  dr_offset, w1, w2);
3365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         dr_base = w2;
3366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         continue;
3367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* else a range [w1+base, w2+base) is denoted */
3370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("    %08lx %08lx %08lx\n",
3371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               dr_offset, w1 + dr_base, w2 + dr_base);
3372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Display .debug_abbrev */
3375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   init_Cursor( &abbv, debug_abbv_img, debug_abbv_sz, 0, barf,
3376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                "Overrun whilst reading .debug_abbrev section" );
3377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_SYMTAB("\n");
3378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_SYMTAB("\n------ The contents of .debug_abbrev ------\n");
3379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (True) {
3380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (is_at_end_Cursor( &abbv ))
3381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
3382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Read one abbreviation table */
3383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("  Number TAG\n");
3384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (True) {
3385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ULong atag;
3386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         UInt  has_children;
3387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ULong acode = get_ULEB128( &abbv );
3388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (acode == 0) break; /* end of the table */
3389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         atag = get_ULEB128( &abbv );
3390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         has_children = get_UChar( &abbv );
3391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("   %llu      %s    [%s]\n",
3392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  acode, ML_(pp_DW_TAG)(atag),
3393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         ML_(pp_DW_children)(has_children));
3394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         while (True) {
3395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ULong at_name = get_ULEB128( &abbv );
3396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ULong at_form = get_ULEB128( &abbv );
3397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (at_name == 0 && at_form == 0) break;
3398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            TRACE_D3("    %18s %s\n",
3399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     ML_(pp_DW_AT)(at_name), ML_(pp_DW_FORM)(at_form));
3400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_SYMTAB("\n");
3404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Now loop over the Compilation Units listed in the .debug_info
3406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      section (see D3SPEC sec 7.5) paras 1 and 2.  Each compilation
3407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      unit contains a Compilation Unit Header followed by precisely
3408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      one DW_TAG_compile_unit or DW_TAG_partial_unit DIE. */
3409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   init_Cursor( &info, debug_info_img, debug_info_sz, 0, barf,
3410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                "Overrun whilst reading .debug_info section" );
3411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* We'll park the harvested type information in here.  Also create
3413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a fake "void" entry with offset D3_FAKEVOID_CUOFF, so we always
3414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      have at least one type entry to refer to.  D3_FAKEVOID_CUOFF is
3415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      huge and presumably will not occur in any valid DWARF3 file --
3416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      it would need to have a .debug_info section 4GB long for that to
3417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      happen.  These type entries end up in the DebugInfo. */
3418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tyents = VG_(newXA)( ML_(dinfo_zalloc),
3419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        "di.readdwarf3.ndrw.1 (TyEnt temp array)",
3420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        ML_(dinfo_free), sizeof(TyEnt) );
3421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { TyEnt tyent;
3422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     VG_(memset)(&tyent, 0, sizeof(tyent));
3423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     tyent.tag   = Te_TyVoid;
3424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     tyent.cuOff = D3_FAKEVOID_CUOFF;
3425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     tyent.Te.TyVoid.isFake = True;
3426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     VG_(addToXA)( tyents, &tyent );
3427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   { TyEnt tyent;
3429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     VG_(memset)(&tyent, 0, sizeof(tyent));
3430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     tyent.tag   = Te_UNKNOWN;
3431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     tyent.cuOff = D3_INVALID_CUOFF;
3432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     VG_(addToXA)( tyents, &tyent );
3433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* This is a tree used to unique-ify the range lists that are
3436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      manufactured by parse_var_DIE.  References to the keys in the
3437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tree wind up in .rngMany fields in TempVars.  We'll need to
3438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      delete this tree, and the XArrays attached to it, at the end of
3439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      this function. */
3440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   rangestree = VG_(newFM)( ML_(dinfo_zalloc),
3441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            "di.readdwarf3.ndrw.2 (rangestree)",
3442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            ML_(dinfo_free),
3443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            (Word(*)(UWord,UWord))cmp__XArrays_of_AddrRange );
3444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* List of variables we're accumulating.  These don't end up in the
3446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      DebugInfo; instead their contents are handed to ML_(addVar) and
3447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the list elements are then deleted. */
3448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tempvars = VG_(newXA)( ML_(dinfo_zalloc),
3449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          "di.readdwarf3.ndrw.3 (TempVar*s array)",
3450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          ML_(dinfo_free),
3451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          sizeof(TempVar*) );
3452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* List of GExprs we're accumulating.  These wind up in the
3454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      DebugInfo. */
3455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   gexprs = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.4",
3456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        ML_(dinfo_free), sizeof(GExpr*) );
3457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* We need a D3TypeParser to keep track of partially constructed
3459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      types.  It'll be discarded as soon as we've completed the CU,
3460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      since the resulting information is tipped in to 'tyents' as it
3461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      is generated. */
3462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(memset)( &typarser, 0, sizeof(typarser) );
3463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typarser.sp = -1;
3464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   typarser.language = '?';
3465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < N_D3_TYPE_STACK; i++) {
3466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typarser.qparentE[i].tag   = Te_EMPTY;
3467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typarser.qparentE[i].cuOff = D3_INVALID_CUOFF;
3468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(memset)( &varparser, 0, sizeof(varparser) );
3471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   varparser.sp = -1;
3472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_D3("\n------ Parsing .debug_info section ------\n");
3474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (True) {
3475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord   cu_start_offset, cu_offset_now;
3476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CUConst cc;
3477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* It may be that the stated size of this CU is larger than the
3478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         amount of stuff actually in it.  icc9 seems to generate CUs
3479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         thusly.  We use these variables to figure out if this is
3480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         indeed the case, and if so how many bytes we need to skip to
3481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         get to the start of the next CU.  Not skipping those bytes
3482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         causes us to misidentify the start of the next CU, and it all
3483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         goes badly wrong after that (not surprisingly). */
3484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord cu_size_including_IniLen, cu_amount_used;
3485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* It seems icc9 finishes the DIE info before debug_info_sz
3487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         bytes have been used up.  So be flexible, and declare the
3488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         sequence complete if there is not enough remaining bytes to
3489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         hold even the smallest conceivable CU header.  (11 bytes I
3490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         reckon). */
3491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* JRS 23Jan09: I suspect this is no longer necessary now that
3492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         the code below contains a 'while (cu_amount_used <
3493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         cu_size_including_IniLen ...'  style loop, which skips over
3494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         any leftover bytes at the end of a CU in the case where the
3495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         CU's stated size is larger than its actual size (as
3496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         determined by reading all its DIEs).  However, for prudence,
3497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         I'll leave the following test in place.  I can't see that a
3498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         CU header can be smaller than 11 bytes, so I don't think
3499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         there's any harm possible through the test -- it just adds
3500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         robustness. */
3501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Word avail = get_remaining_length_Cursor( &info );
3502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (avail < 11) {
3503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (avail > 0)
3504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            TRACE_D3("new_dwarf3_reader_wrk: warning: "
3505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     "%ld unused bytes after end of DIEs\n", avail);
3506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
3507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Check the varparser's stack is in a sane state. */
3510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(varparser.sp == -1);
3511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for (i = 0; i < N_D3_VAR_STACK; i++) {
3512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(varparser.ranges[i] == NULL);
3513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(varparser.level[i] == 0);
3514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      for (i = 0; i < N_D3_TYPE_STACK; i++) {
3516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(typarser.qparentE[i].cuOff == D3_INVALID_CUOFF);
3517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(typarser.qparentE[i].tag   == Te_EMPTY);
3518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(typarser.qlevel[i] == 0);
3519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cu_start_offset = get_position_of_Cursor( &info );
3522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("\n");
3523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("  Compilation Unit @ offset 0x%lx:\n", cu_start_offset);
3524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* parse_CU_header initialises the CU's set_abbv_Cursor cache
3525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (saC_cache) */
3526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      parse_CU_Header( &cc, td3, &info,
3527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       (UChar*)debug_abbv_img, debug_abbv_sz );
3528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc.debug_str_img    = debug_str_img;
3529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc.debug_str_sz     = debug_str_sz;
3530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc.debug_ranges_img = debug_ranges_img;
3531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc.debug_ranges_sz  = debug_ranges_sz;
3532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc.debug_loc_img    = debug_loc_img;
3533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc.debug_loc_sz     = debug_loc_sz;
3534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc.debug_line_img   = debug_line_img;
3535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc.debug_line_sz    = debug_line_sz;
3536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc.debug_info_img   = debug_info_img;
3537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc.debug_info_sz    = debug_info_sz;
3538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc.cu_start_offset  = cu_start_offset;
3539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc.di = di;
3540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* The CU's svma can be deduced by looking at the AT_low_pc
3541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         value in the top level TAG_compile_unit, which is the topmost
3542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         DIE.  We'll leave it for the 'varparser' to acquire that info
3543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         and fill it in -- since it is the only party to want to know
3544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         it. */
3545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc.cu_svma_known = False;
3546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cc.cu_svma       = 0;
3547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Create a fake outermost-level range covering the entire
3549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         address range.  So we always have *something* to catch all
3550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         variable declarations. */
3551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      varstack_push( &cc, &varparser, td3,
3552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     unitary_range_list(0UL, ~0UL),
3553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     -1, False/*isFunc*/, NULL/*fbGX*/ );
3554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* And set up the file name table.  When we come across the top
3556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         level DIE for this CU (which is what the next call to
3557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         read_DIE should process) we will copy all the file names out
3558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         of the .debug_line img area and use this table to look up the
3559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         copies when we later see filename numbers in DW_TAG_variables
3560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         etc. */
3561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(!varparser.filenameTable );
3562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      varparser.filenameTable
3563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.5",
3564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       ML_(dinfo_free),
3565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       sizeof(UChar*) );
3566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(varparser.filenameTable);
3567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Now read the one-and-only top-level DIE for this CU. */
3569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(varparser.sp == 0);
3570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      read_DIE( rangestree,
3571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                tyents, tempvars, gexprs,
3572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                &typarser, &varparser,
3573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                &info, td3, &cc, 0 );
3574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cu_offset_now = get_position_of_Cursor( &info );
3576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (0) VG_(printf)("Travelled: %lu  size %llu\n",
3578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         cu_offset_now - cc.cu_start_offset,
3579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         cc.unit_length + (cc.is_dw64 ? 12 : 4));
3580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* How big the CU claims it is .. */
3582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cu_size_including_IniLen = cc.unit_length + (cc.is_dw64 ? 12 : 4);
3583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* .. vs how big we have found it to be */
3584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cu_amount_used = cu_offset_now - cc.cu_start_offset;
3585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (1) TRACE_D3("offset now %ld, d-i-size %ld\n",
3587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                      cu_offset_now, debug_info_sz);
3588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (cu_offset_now > debug_info_sz)
3589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         barf("toplevel DIEs beyond end of CU");
3590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* If the CU is bigger than it claims to be, we've got a serious
3592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         problem. */
3593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (cu_amount_used > cu_size_including_IniLen)
3594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         barf("CU's actual size appears to be larger than it claims it is");
3595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* If the CU is smaller than it claims to be, we need to skip some
3597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         bytes.  Loop updates cu_offset_new and cu_amount_used. */
3598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (cu_amount_used < cu_size_including_IniLen
3599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             && get_remaining_length_Cursor( &info ) > 0) {
3600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (0) VG_(printf)("SKIP\n");
3601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (void)get_UChar( &info );
3602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         cu_offset_now = get_position_of_Cursor( &info );
3603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         cu_amount_used = cu_offset_now - cc.cu_start_offset;
3604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (cu_offset_now == debug_info_sz)
3607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
3608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Preen to level -2.  DIEs have level >= 0 so -2 cannot occur
3610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         anywhere else at all.  Our fake the-entire-address-space
3611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         range is at level -1, so preening to -2 should completely
3612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         empty the stack out. */
3613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("\n");
3614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      varstack_preen( &varparser, td3, -2 );
3615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Similarly, empty the type stack out. */
3616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      typestack_preen( &typarser, td3, -2 );
3617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* else keep going */
3618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("set_abbv_Cursor cache: %lu queries, %lu misses\n",
3620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               cc.saC_cache_queries, cc.saC_cache_misses);
3621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(varparser.filenameTable );
3623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(deleteXA)( varparser.filenameTable );
3624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      varparser.filenameTable = NULL;
3625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* From here on we're post-processing the stuff we got
3628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      out of the .debug_info section. */
3629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (td3) {
3630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("\n");
3631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ML_(pp_TyEnts)(tyents, "Initial type entity (TyEnt) array");
3632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("\n");
3633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("------ Compressing type entries ------\n");
3634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tyents_cache = ML_(dinfo_zalloc)( "di.readdwarf3.ndrw.6",
3637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                     sizeof(TyEntIndexCache) );
3638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(TyEntIndexCache__invalidate)( tyents_cache );
3639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   dedup_types( td3, tyents, tyents_cache );
3640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (td3) {
3641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("\n");
3642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ML_(pp_TyEnts)(tyents, "After type entity (TyEnt) compression");
3643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_D3("\n");
3646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_D3("------ Resolving the types of variables ------\n" );
3647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   resolve_variable_types( barf, tyents, tyents_cache, tempvars );
3648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Copy all the non-INDIR tyents into a new table.  For large
3650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      .so's, about 90% of the tyents will by now have been resolved to
3651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      INDIRs, and we no longer need them, and so don't need to store
3652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      them. */
3653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tyents_to_keep
3654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      = VG_(newXA)( ML_(dinfo_zalloc),
3655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    "di.readdwarf3.ndrw.7 (TyEnt to-keep array)",
3656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    ML_(dinfo_free), sizeof(TyEnt) );
3657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n = VG_(sizeXA)( tyents );
3658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < n; i++) {
3659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TyEnt* ent = VG_(indexXA)( tyents, i );
3660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ent->tag != Te_INDIR)
3661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(addToXA)( tyents_to_keep, ent );
3662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(deleteXA)( tyents );
3665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tyents = NULL;
3666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(dinfo_free)( tyents_cache );
3667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tyents_cache = NULL;
3668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Sort tyents_to_keep so we can lookup in it.  A complete (if
3670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      minor) waste of time, since tyents itself is sorted, but
3671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      necessary since VG_(lookupXA) refuses to cooperate if we
3672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      don't. */
3673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(setCmpFnXA)(
3674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      tyents_to_keep,
3675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (Int(*)(void*,void*)) ML_(TyEnt__cmp_by_cuOff_only)
3676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   );
3677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(sortXA)( tyents_to_keep );
3678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Enable cacheing on tyents_to_keep */
3680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tyents_to_keep_cache
3681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      = ML_(dinfo_zalloc)( "di.readdwarf3.ndrw.8",
3682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                           sizeof(TyEntIndexCache) );
3683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(TyEntIndexCache__invalidate)( tyents_to_keep_cache );
3684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* And record the tyents in the DebugInfo.  We do this before
3686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      starting to hand variables to ML_(addVar), since if ML_(addVar)
3687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      wants to do debug printing (of the types of said vars) then it
3688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      will need the tyents.*/
3689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(!di->admin_tyents);
3690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   di->admin_tyents = tyents_to_keep;
3691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Bias all the location expressions. */
3693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_D3("\n");
3694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_D3("------ Biasing the location expressions ------\n" );
3695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n = VG_(sizeXA)( gexprs );
3697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < n; i++) {
3698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      gexpr = *(GExpr**)VG_(indexXA)( gexprs, i );
3699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      bias_GX( gexpr, di );
3700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_D3("\n");
3703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_D3("------ Acquired the following variables: ------\n\n");
3704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Park (pointers to) all the vars in an XArray, so we can look up
3706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      abstract origins quickly.  The array is sorted (hence, looked-up
3707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      by) the .dioff fields.  Since the .dioffs should be in strictly
3708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ascending order, there is no need to sort the array after
3709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      construction.  The ascendingness is however asserted for. */
3710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   dioff_lookup_tab
3711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.9",
3712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    ML_(dinfo_free),
3713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    sizeof(TempVar*) );
3714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(dioff_lookup_tab);
3715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n = VG_(sizeXA)( tempvars );
3717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < n; i++) {
3718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      varp = *(TempVar**)VG_(indexXA)( tempvars, i );
3719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (i > 0) {
3720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         varp2 = *(TempVar**)VG_(indexXA)( tempvars, i-1 );
3721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* why should this hold?  Only, I think, because we've
3722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            constructed the array by reading .debug_info sequentially,
3723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            and so the array .dioff fields should reflect that, and be
3724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            strictly ascending. */
3725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(varp2->dioff < varp->dioff);
3726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(addToXA)( dioff_lookup_tab, &varp );
3728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(setCmpFnXA)( dioff_lookup_tab, cmp_TempVar_by_dioff );
3730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(sortXA)( dioff_lookup_tab ); /* POINTLESS; FIXME: rm */
3731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Now visit each var.  Collect up as much info as possible for
3733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      each var and hand it to ML_(addVar). */
3734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n = VG_(sizeXA)( tempvars );
3735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (j = 0; j < n; j++) {
3736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TyEnt* ent;
3737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      varp = *(TempVar**)VG_(indexXA)( tempvars, j );
3738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Possibly show .. */
3740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (td3) {
3741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("<%lx> addVar: level %d: %s :: ",
3742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     varp->dioff,
3743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     varp->level,
3744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     varp->name ? varp->name : (UChar*)"<anon_var>" );
3745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (varp->typeR) {
3746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ML_(pp_TyEnt_C_ishly)( tyents_to_keep, varp->typeR );
3747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
3748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_(printf)("NULL");
3749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("\n  Loc=");
3751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (varp->gexpr) {
3752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ML_(pp_GX)(varp->gexpr);
3753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
3754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_(printf)("NULL");
3755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("\n");
3757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (varp->fbGX) {
3758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_(printf)("  FrB=");
3759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ML_(pp_GX)( varp->fbGX );
3760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_(printf)("\n");
3761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
3762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_(printf)("  FrB=none\n");
3763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(printf)("  declared at: %s:%d\n",
3765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     varp->fName ? varp->fName : (UChar*)"NULL",
3766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     varp->fLine );
3767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (varp->absOri != (UWord)D3_INVALID_CUOFF)
3768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            VG_(printf)("  abstract origin: <%lx>\n", varp->absOri);
3769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Skip variables which have no location.  These must be
3772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         abstract instances; they are useless as-is since with no
3773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         location they have no specified memory location.  They will
3774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         presumably be referred to via the absOri fields of other
3775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         variables. */
3776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!varp->gexpr) {
3777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("  SKIP (no location)\n\n");
3778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         continue;
3779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* So it has a location, at least.  If it refers to some other
3782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         entry through its absOri field, pull in further info through
3783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         that. */
3784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (varp->absOri != (UWord)D3_INVALID_CUOFF) {
3785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Bool found;
3786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Word ixFirst, ixLast;
3787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TempVar key;
3788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TempVar* keyp = &key;
3789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TempVar *varAI;
3790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         VG_(memset)(&key, 0, sizeof(key)); /* not necessary */
3791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         key.dioff = varp->absOri; /* this is what we want to find */
3792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         found = VG_(lookupXA)( dioff_lookup_tab, &keyp,
3793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                &ixFirst, &ixLast );
3794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (!found) {
3795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            /* barf("DW_AT_abstract_origin can't be resolved"); */
3796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            TRACE_D3("  SKIP (DW_AT_abstract_origin can't be resolved)\n\n");
3797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            continue;
3798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
3799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* If the following fails, there is more than one entry with
3800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            the same dioff.  Which can't happen. */
3801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(ixFirst == ixLast);
3802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         varAI = *(TempVar**)VG_(indexXA)( dioff_lookup_tab, ixFirst );
3803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* stay sane */
3804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(varAI);
3805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vg_assert(varAI->dioff == varp->absOri);
3806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Copy what useful info we can. */
3808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (varAI->typeR && !varp->typeR)
3809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            varp->typeR = varAI->typeR;
3810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (varAI->name && !varp->name)
3811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            varp->name = varAI->name;
3812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (varAI->fName && !varp->fName)
3813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            varp->fName = varAI->fName;
3814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (varAI->fLine > 0 && varp->fLine == 0)
3815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            varp->fLine = varAI->fLine;
3816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Give it a name if it doesn't have one. */
3819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (!varp->name)
3820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         varp->name = ML_(addStr)( di, "<anon_var>", -1 );
3821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* So now does it have enough info to be useful? */
3823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* NOTE: re typeR: this is a hack.  If typeR is Te_UNKNOWN then
3824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         the type didn't get resolved.  Really, in that case
3825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         something's broken earlier on, and should be fixed, rather
3826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         than just skipping the variable. */
3827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ent = ML_(TyEnts__index_by_cuOff)( tyents_to_keep,
3828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                         tyents_to_keep_cache,
3829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                         varp->typeR );
3830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* The next two assertions should be guaranteed by
3831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         our previous call to resolve_variable_types. */
3832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(ent);
3833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(ML_(TyEnt__is_type)(ent) || ent->tag == Te_UNKNOWN);
3834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (ent->tag == Te_UNKNOWN) continue;
3836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(varp->gexpr);
3838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(varp->name);
3839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(varp->typeR);
3840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(varp->level >= 0);
3841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Ok.  So we're going to keep it.  Call ML_(addVar) once for
3843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         each address range in which the variable exists. */
3844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("  ACQUIRE for range(s) ");
3845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      { AddrRange  oneRange;
3846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        AddrRange* varPcRanges;
3847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        Word       nVarPcRanges;
3848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        /* Set up to iterate over address ranges, however
3849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           represented. */
3850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if (varp->nRanges == 0 || varp->nRanges == 1) {
3851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           vg_assert(!varp->rngMany);
3852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           if (varp->nRanges == 0) {
3853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              vg_assert(varp->rngOneMin == 0);
3854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              vg_assert(varp->rngOneMax == 0);
3855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           }
3856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           nVarPcRanges = varp->nRanges;
3857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           oneRange.aMin = varp->rngOneMin;
3858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           oneRange.aMax = varp->rngOneMax;
3859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           varPcRanges = &oneRange;
3860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        } else {
3861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           vg_assert(varp->rngMany);
3862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           vg_assert(varp->rngOneMin == 0);
3863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           vg_assert(varp->rngOneMax == 0);
3864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           nVarPcRanges = VG_(sizeXA)(varp->rngMany);
3865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           vg_assert(nVarPcRanges >= 2);
3866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           vg_assert(nVarPcRanges == (Word)varp->nRanges);
3867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           varPcRanges = VG_(indexXA)(varp->rngMany, 0);
3868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
3869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if (varp->level == 0)
3870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           vg_assert( nVarPcRanges == 1 );
3871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        /* and iterate */
3872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        for (i = 0; i < nVarPcRanges; i++) {
3873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           Addr pcMin = varPcRanges[i].aMin;
3874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           Addr pcMax = varPcRanges[i].aMax;
3875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           vg_assert(pcMin <= pcMax);
3876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           /* Level 0 is the global address range.  So at level 0 we
3877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              don't want to bias pcMin/pcMax; but at all other levels
3878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              we do since those are derived from svmas in the Dwarf
3879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              we're reading.  Be paranoid ... */
3880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           if (varp->level == 0) {
3881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              vg_assert(pcMin == (Addr)0);
3882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              vg_assert(pcMax == ~(Addr)0);
3883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           } else {
3884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              /* vg_assert(pcMin > (Addr)0);
3885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 No .. we can legitimately expect to see ranges like
3886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 0x0-0x11D (pre-biasing, of course). */
3887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              vg_assert(pcMax < ~(Addr)0);
3888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           }
3889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           /* Apply text biasing, for non-global variables. */
3891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           if (varp->level > 0) {
3892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              pcMin += di->text_debug_bias;
3893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              pcMax += di->text_debug_bias;
3894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           }
3895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           if (i > 0 && (i%2) == 0)
3897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              TRACE_D3("\n                       ");
3898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           TRACE_D3("[%#lx,%#lx] ", pcMin, pcMax );
3899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           ML_(addVar)(
3901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              di, varp->level,
3902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  pcMin, pcMax,
3903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  varp->name,  varp->typeR,
3904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  varp->gexpr, varp->fbGX,
3905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  varp->fName, varp->fLine, td3
3906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           );
3907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
3908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
3909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("\n\n");
3911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* and move on to the next var */
3912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Now free all the TempVars */
3915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n = VG_(sizeXA)( tempvars );
3916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for (i = 0; i < n; i++) {
3917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      varp = *(TempVar**)VG_(indexXA)( tempvars, i );
3918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ML_(dinfo_free)(varp);
3919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(deleteXA)( tempvars );
3921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tempvars = NULL;
3922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* and the temp lookup table */
3924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(deleteXA)( dioff_lookup_tab );
3925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* and the ranges tree.  Note that we need to also free the XArrays
3927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      which constitute the keys, hence pass VG_(deleteXA) as a
3928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      key-finalizer. */
3929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_(deleteFM)( rangestree, (void(*)(UWord))VG_(deleteXA), NULL );
3930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* and the tyents_to_keep cache */
3932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(dinfo_free)( tyents_to_keep_cache );
3933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tyents_to_keep_cache = NULL;
3934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* and the file name table (just the array, not the entries
3936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      themselves).  (Apparently, 2008-Oct-23, varparser.filenameTable
3937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      can be NULL here, for icc9 generated Dwarf3.  Not sure what that
3938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      signifies (a deeper problem with the reader?)) */
3939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (varparser.filenameTable) {
3940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(deleteXA)( varparser.filenameTable );
3941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      varparser.filenameTable = NULL;
3942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
3943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* record the GExprs in di so they can be freed later */
3945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(!di->admin_gexprs);
3946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   di->admin_gexprs = gexprs;
3947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
3951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
3952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- The "new" DWARF3 reader -- top level control logic   ---*/
3953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                                      ---*/
3954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/
3955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3956b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic Bool               d3rd_jmpbuf_valid  = False;
3957b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic HChar*             d3rd_jmpbuf_reason = NULL;
3958b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic VG_MINIMAL_JMP_BUF(d3rd_jmpbuf);
3959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic __attribute__((noreturn)) void barf ( HChar* reason ) {
3961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(d3rd_jmpbuf_valid);
3962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   d3rd_jmpbuf_reason = reason;
3963b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_MINIMAL_LONGJMP(d3rd_jmpbuf);
3964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*NOTREACHED*/
3965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(0);
3966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
3967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid
3970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownML_(new_dwarf3_reader) (
3971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct _DebugInfo* di,
3972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar* debug_info_img,   SizeT debug_info_sz,
3973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar* debug_abbv_img,   SizeT debug_abbv_sz,
3974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar* debug_line_img,   SizeT debug_line_sz,
3975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar* debug_str_img,    SizeT debug_str_sz,
3976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar* debug_ranges_img, SizeT debug_ranges_sz,
3977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar* debug_loc_img,    SizeT debug_loc_sz
3978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown)
3979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
3980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   volatile Int  jumped;
3981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   volatile Bool td3 = di->trace_symtab;
3982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Run the _wrk function to read the dwarf3.  If it succeeds, it
3984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      just returns normally.  If there is any failure, it longjmp's
3985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      back here, having first set d3rd_jmpbuf_reason to something
3986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      useful. */
3987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(d3rd_jmpbuf_valid  == False);
3988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(d3rd_jmpbuf_reason == NULL);
3989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   d3rd_jmpbuf_valid = True;
3991b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   jumped = VG_MINIMAL_SETJMP(d3rd_jmpbuf);
3992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (jumped == 0) {
3993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* try this ... */
3994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      new_dwarf3_reader_wrk( di, barf,
3995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             debug_info_img,   debug_info_sz,
3996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             debug_abbv_img,   debug_abbv_sz,
3997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             debug_line_img,   debug_line_sz,
3998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             debug_str_img,    debug_str_sz,
3999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             debug_ranges_img, debug_ranges_sz,
4000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                             debug_loc_img,    debug_loc_sz );
4001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d3rd_jmpbuf_valid = False;
4002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("\n------ .debug_info reading was successful ------\n");
4003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } else {
4004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* It longjmp'd. */
4005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d3rd_jmpbuf_valid = False;
4006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Can't longjump without giving some sort of reason. */
4007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(d3rd_jmpbuf_reason != NULL);
4008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("\n------ .debug_info reading failed ------\n");
4010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ML_(symerr)(di, True, d3rd_jmpbuf_reason);
4012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
4013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   d3rd_jmpbuf_valid  = False;
4015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   d3rd_jmpbuf_reason = NULL;
4016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
4017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --- Unused code fragments which might be useful one day. --- */
4021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0
4023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Read the arange tables */
4024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_SYMTAB("\n");
4025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_SYMTAB("\n------ The contents of .debug_arange ------\n");
4026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   init_Cursor( &aranges, debug_aranges_img,
4027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                debug_aranges_sz, 0, barf,
4028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                "Overrun whilst reading .debug_aranges section" );
4029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (True) {
4030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ULong  len, d_i_offset;
4031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool   is64;
4032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UShort version;
4033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar  asize, segsize;
4034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (is_at_end_Cursor( &aranges ))
4036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         break;
4037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Read one arange thingy */
4038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* initial_length field */
4039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      len = get_Initial_Length( &is64, &aranges,
4040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               "in .debug_aranges: invalid initial-length field" );
4041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      version    = get_UShort( &aranges );
4042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      d_i_offset = get_Dwarfish_UWord( &aranges, is64 );
4043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      asize      = get_UChar( &aranges );
4044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      segsize    = get_UChar( &aranges );
4045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("  Length:                   %llu\n", len);
4046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("  Version:                  %d\n", (Int)version);
4047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("  Offset into .debug_info:  %llx\n", d_i_offset);
4048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("  Pointer Size:             %d\n", (Int)asize);
4049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("  Segment Size:             %d\n", (Int)segsize);
4050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("\n");
4051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      TRACE_D3("    Address            Length\n");
4052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while ((get_position_of_Cursor( &aranges ) % (2 * asize)) > 0) {
4054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         (void)get_UChar( & aranges );
4055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      while (True) {
4057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ULong address = get_Dwarfish_UWord( &aranges, asize==8 );
4058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ULong length = get_Dwarfish_UWord( &aranges, asize==8 );
4059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         TRACE_D3("    0x%016llx 0x%llx\n", address, length);
4060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (address == 0 && length == 0) break;
4061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
4062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
4063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   TRACE_SYMTAB("\n");
4064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
4065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif // defined(VGO_linux) || defined(VGO_darwin)
4067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
4069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end                                                          ---*/
4070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
4071