readdwarf3.c revision 896a3bfd1b98aa3358a2e77be3bb728cb3d2926f
15d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* -*- mode: C; c-basic-offset: 3; -*- */
2b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------------*/
4fba428cd266b8a39db641c5fd9523daa8939bed0tom/*--- Read DWARF3/4 ".debug_info" sections (DIE trees).            ---*/
5b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                 readdwarf3.c ---*/
6b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------------*/
7b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
8b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*
9b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   This file is part of Valgrind, a dynamic binary instrumentation
10b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   framework.
11b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
120f157ddb404bcde7815a1c5bf2d7e41c114f3d73sewardj   Copyright (C) 2008-2013 OpenWorks LLP
13b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      info@open-works.co.uk
14b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
15b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   This program is free software; you can redistribute it and/or
16b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   modify it under the terms of the GNU General Public License as
17b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   published by the Free Software Foundation; either version 2 of the
18b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   License, or (at your option) any later version.
19b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
20b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   This program is distributed in the hope that it will be useful, but
21b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   WITHOUT ANY WARRANTY; without even the implied warranty of
22b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   General Public License for more details.
24b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
25b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   You should have received a copy of the GNU General Public License
26b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   along with this program; if not, write to the Free Software
27b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   02111-1307, USA.
29b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
30b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   The GNU General Public License is contained in the file COPYING.
31b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
32b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Neither the names of the U.S. Department of Energy nor the
33b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   University of California nor the names of its contributors may be
34b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   used to endorse or promote products derived from this software
35b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   without prior written permission.
36b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/
37b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
388b68b64759254d514d98328c496cbd88cde4c9a5njn#if defined(VGO_linux) || defined(VGO_darwin)
398b68b64759254d514d98328c496cbd88cde4c9a5njn
40b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* REFERENCE (without which this code will not make much sense):
41b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
42b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   DWARF Debugging Information Format, Version 3,
43b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   dated 20 December 2005 (the "D3 spec").
44b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
45b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Available at http://www.dwarfstd.org/Dwarf3.pdf.  There's also a
46b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   .doc (MS Word) version, but for some reason the section numbers
47b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   between the Word and PDF versions differ by 1 in the first digit.
48b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   All section references in this code are to the PDF version.
49b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
50b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   CURRENT HACKS:
51b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
52b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   DW_TAG_{const,volatile}_type no DW_AT_type is allowed; it is
53b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      assumed to mean "const void" or "volatile void" respectively.
54b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GDB appears to interpret them like this, anyway.
55b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
56b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   In many cases it is important to know the svma of a CU (the "base
57b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   address of the CU", as the D3 spec calls it).  There are some
58b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   situations in which the spec implies this value is unknown, but the
59b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Dwarf3 produced by gcc-4.1 seems to assume is not unknown but
60b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   merely zero when not explicitly stated.  So we too have to make
61b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   that assumption.
62b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   POTENTIAL BUG?  Spotted 6 Sept 08.  Why doesn't
649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   unitary_range_list() bias the resulting range list in the same way
659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   that its more general cousin, get_range_list(), does?  I don't
669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   know.
679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
68b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TODO, 2008 Feb 17:
69b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
70b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   get rid of cu_svma_known and document the assumed-zero svma hack.
71b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
72b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ML_(sizeOfType): differentiate between zero sized types and types
73b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for which the size is unknown.  Is this important?  I don't know.
74b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
75a2af13d238de6b212f1d69e7b316538f37a7abbasewardj   DW_TAG_array_types: deal with explicit sizes (currently we compute
76b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   the size from the bounds and the element size, although that's
77b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   fragile, if the bounds incompletely specified, or completely
78b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   absent)
79b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
80b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Document reason for difference (by 1) of stack preening depth in
81b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parse_var_DIE vs parse_type_DIE.
82b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
83b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Don't hand to ML_(addVars), vars whose locations are entirely in
84b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   registers (DW_OP_reg*).  This is merely a space-saving
85b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   optimisation, as ML_(evaluate_Dwarf3_Expr) should handle these
86b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   expressions correctly, by failing to evaluate them and hence
87b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   effectively ignoring the variable with which they are associated.
88b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
89a2af13d238de6b212f1d69e7b316538f37a7abbasewardj   Deal with DW_TAG_array_types which have element size != stride
90b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
91b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   In some cases, the info for a variable is split between two
92b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   different DIEs (generally a declarer and a definer).  We punt on
93b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   these.  Could do better here.
94b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
95b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   The 'data_bias' argument passed to the expression evaluator
96b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   (ML_(evaluate_Dwarf3_Expr)) should really be changed to a
97b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   MaybeUWord, to make it clear when we do vs don't know what it is
98b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for the evaluation of an expression.  At the moment zero is passed
99b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for this parameter in the don't know case.  That's a bit fragile
100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   and obscure; using a MaybeUWord would be clearer.
101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   POTENTIAL PERFORMANCE IMPROVEMENTS:
103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Currently, duplicate removal and all other queries for the type
1059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   entities array is done using cuOffset-based pointing, which
1069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   involves a binary search (VG_(lookupXA)) for each access.  This is
1079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   wildly inefficient, although simple.  It would be better to
1089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   translate all the cuOffset-based references (iow, all the "R" and
1099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   "Rs" fields in the TyEnts in 'tyents') to direct index numbers in
1109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   'tyents' right at the start of dedup_types(), and use direct
1119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   indexing (VG_(indexXA)) wherever possible after that.
1129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
1139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   cmp__XArrays_of_AddrRange is also a performance bottleneck.  Move
1149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(indexXA) into pub_tool_xarray.h so it can be inlined at all use
1159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   points, and possibly also make an _UNCHECKED version which skips
1169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   the range checks in performance-critical situations such as this.
117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Handle interaction between read_DIE and parse_{var,type}_DIE
119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   better.  Currently read_DIE reads the entire DIE just to find where
120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   the end is (and for debug printing), so that it can later reliably
121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   move the cursor to the end regardless of what parse_{var,type}_DIE
122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   do.  This means many DIEs (most, even?) are read twice.  It would
123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   be smarter to make parse_{var,type}_DIE return a Bool indicating
124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   whether or not they advanced the DIE cursor, and only if they
125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   didn't should read_DIE itself read through the DIE.
126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ML_(addVar) and add_var_to_arange: quite a lot of DiAddrRanges have
128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   zero variables in their .vars XArray.  Rather than have an XArray
129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   with zero elements (which uses 2 malloc'd blocks), allow the .vars
130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   pointer to be NULL in this case.
131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   More generally, reduce the amount of memory allocated and freed
133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while reading Dwarf3 type/variable information.  Even modest (20MB)
134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   objects cause this module to allocate and free hundreds of
135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   thousands of small blocks, and ML_(arena_malloc) and its various
136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   groupies always show up at the top of performance profiles. */
137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_basics.h"
139588658b13b5ad77672f323d48fe9da0ca60b0bcbtom#include "pub_core_debuginfo.h"
140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_libcbase.h"
141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_libcassert.h"
142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_libcprint.h"
1436c591e15c1d6402a2a755310f005f795b68e7e38sewardj#include "pub_core_libcsetjmp.h"   // setjmp facilities
144d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj#include "pub_core_hashtable.h"
145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_options.h"
146f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_tooliface.h"    /* VG_(needs) */
147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "pub_core_xarray.h"
1489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj#include "pub_core_wordfm.h"
149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_misc.h"             /* dinfo_zalloc/free */
1505d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj#include "priv_image.h"
151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_tytypes.h"
152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_d3basics.h"
153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_storage.h"
154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_readdwarf3.h"       /* self */
155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Basic machinery for parsing DIEs.                    ---*/
160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define TRACE_D3(format, args...) \
164a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (UNLIKELY(td3)) { VG_(printf)(format, ## args); }
165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj#define D3_INVALID_CUOFF  ((UWord)(-1UL))
1679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj#define D3_FAKEVOID_CUOFF ((UWord)(-2UL))
168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct {
1715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice sli;      // to which this cursor applies
1725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiOffT  sli_next; // offset in underlying DiImage; must be >= sli.ioff
1736bd9dc18c043927c1196caba20a327238a179c42florian      void (*barf)( const HChar* ) __attribute__((noreturn));
1746bd9dc18c043927c1196caba20a327238a179c42florian      const HChar* barfstr;
175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Cursor;
177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic inline Bool is_sane_Cursor ( Cursor* c ) {
179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (!c)                return False;
180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (!c->barf)          return False;
181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (!c->barfstr)       return False;
1825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (!ML_(sli_is_valid)(c->sli))    return False;
1835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (c->sli.ioff == DiOffT_INVALID) return False;
1845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (c->sli_next < c->sli.ioff)     return False;
185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return True;
186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj// Initialise a cursor from a DiSlice (ELF section, really) so as to
1895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj// start reading at offset |sli_initial_offset| from the start of the
1905d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj// slice.
1915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic void init_Cursor ( /*OUT*/Cursor* c,
1925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                          DiSlice sli,
1935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                          ULong   sli_initial_offset,
1945d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                          __attribute__((noreturn)) void (*barf)(const HChar*),
1956bd9dc18c043927c1196caba20a327238a179c42florian                          const HChar* barfstr )
196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(c);
1985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   VG_(bzero_inline)(c, sizeof(*c));
1995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli              = sli;
2005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next         = c->sli.ioff + sli_initial_offset;
201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   c->barf             = barf;
202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   c->barfstr          = barfstr;
203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool is_at_end_Cursor ( Cursor* c ) {
207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
2085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return c->sli_next >= c->sli.ioff + c->sli.szB;
209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline ULong get_position_of_Cursor ( Cursor* c ) {
212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
2135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return c->sli_next - c->sli.ioff;
214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline void set_position_of_Cursor ( Cursor* c, ULong pos ) {
2165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next = c->sli.ioff + pos;
217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic /*signed*/Long get_remaining_length_Cursor ( Cursor* c ) {
221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
2225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return c->sli.ioff + c->sli.szB - c->sli_next;
223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2255d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj//static void* get_address_of_Cursor ( Cursor* c ) {
2265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj//   vg_assert(is_sane_Cursor(c));
2275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj//   return &c->region_start_img[ c->region_next ];
2285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj//}
2295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
2305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic DiCursor get_DiCursor_from_Cursor ( Cursor* c ) {
2315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return mk_DiCursor(c->sli.img, c->sli_next);
232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* FIXME: document assumptions on endianness for
235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   get_UShort/UInt/ULong. */
236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic inline UChar get_UChar ( Cursor* c ) {
237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar r;
2385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   vg_assert(is_sane_Cursor(c));
2395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (c->sli_next + sizeof(UChar) > c->sli.ioff + c->sli.szB) {
240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c->barf(c->barfstr);
241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*NOTREACHED*/
242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(0);
243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   r = ML_(img_get_UChar)(c->sli.img, c->sli_next);
2455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next += sizeof(UChar);
246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return r;
247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic UShort get_UShort ( Cursor* c ) {
249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UShort r;
250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
2515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (c->sli_next + sizeof(UShort) > c->sli.ioff + c->sli.szB) {
252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c->barf(c->barfstr);
253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*NOTREACHED*/
254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(0);
255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   r = ML_(img_get_UShort)(c->sli.img, c->sli_next);
2575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next += sizeof(UShort);
258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return r;
259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic UInt get_UInt ( Cursor* c ) {
261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt r;
262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
2635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (c->sli_next + sizeof(UInt) > c->sli.ioff + c->sli.szB) {
264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c->barf(c->barfstr);
265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*NOTREACHED*/
266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(0);
267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   r = ML_(img_get_UInt)(c->sli.img, c->sli_next);
2695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next += sizeof(UInt);
270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return r;
271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic ULong get_ULong ( Cursor* c ) {
273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ULong r;
274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
2755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (c->sli_next + sizeof(ULong) > c->sli.ioff + c->sli.szB) {
276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c->barf(c->barfstr);
277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*NOTREACHED*/
278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(0);
279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   r = ML_(img_get_ULong)(c->sli.img, c->sli_next);
2815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next += sizeof(ULong);
282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return r;
283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic ULong get_ULEB128 ( Cursor* c ) {
285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ULong result;
286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int   shift;
287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar byte;
288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* unroll first iteration */
289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   byte = get_UChar( c );
290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   result = (ULong)(byte & 0x7f);
291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (LIKELY(!(byte & 0x80))) return result;
292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   shift = 7;
293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* end unroll first iteration */
294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   do {
295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      byte = get_UChar( c );
296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      result |= ((ULong)(byte & 0x7f)) << shift;
297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      shift += 7;
298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } while (byte & 0x80);
299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return result;
300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Long get_SLEB128 ( Cursor* c ) {
302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ULong  result = 0;
303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int    shift = 0;
304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar  byte;
305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   do {
306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      byte = get_UChar(c);
307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      result |= ((ULong)(byte & 0x7f)) << shift;
308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      shift += 7;
309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } while (byte & 0x80);
310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (shift < 64 && (byte & 0x40))
311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      result |= -(1ULL << shift);
312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return result;
313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Assume 'c' points to the start of a string.  Return a DiCursor of
3165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   whatever it points at, and advance it past the terminating zero.
3175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   This makes it safe for the caller to then copy the string with
3185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   ML_(addStr), since (w.r.t. image overruns) the process of advancing
3195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   past the terminating zero will already have "vetted" the string. */
3205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic DiCursor get_AsciiZ ( Cursor* c ) {
3215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UChar uc;
3225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiCursor res = get_DiCursor_from_Cursor(c);
323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   do { uc = get_UChar(c); } while (uc != 0);
324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return res;
325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic ULong peek_ULEB128 ( Cursor* c ) {
3285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiOffT here = c->sli_next;
3295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   ULong  r    = get_ULEB128( c );
3305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next = here;
331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return r;
332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic UChar peek_UChar ( Cursor* c ) {
3345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiOffT here = c->sli_next;
3355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UChar  r    = get_UChar( c );
3365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next = here;
337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return r;
338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic ULong get_Dwarfish_UWord ( Cursor* c, Bool is_dw64 ) {
341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return is_dw64 ? get_ULong(c) : (ULong) get_UInt(c);
342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic UWord get_UWord ( Cursor* c ) {
345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(sizeof(UWord) == sizeof(void*));
346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (sizeof(UWord) == 4) return get_UInt(c);
347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (sizeof(UWord) == 8) return get_ULong(c);
348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(0);
349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Read a DWARF3 'Initial Length' field */
352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic ULong get_Initial_Length ( /*OUT*/Bool* is64,
353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                  Cursor* c,
3546bd9dc18c043927c1196caba20a327238a179c42florian                                  const HChar* barfMsg )
355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ULong w64;
357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt  w32;
358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   *is64 = False;
359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   w32 = get_UInt( c );
360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (w32 >= 0xFFFFFFF0 && w32 < 0xFFFFFFFF) {
361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c->barf( barfMsg );
362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   else if (w32 == 0xFFFFFFFF) {
364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      *is64 = True;
365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      w64   = get_ULong( c );
366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } else {
367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      *is64 = False;
368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      w64 = (ULong)w32;
369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return w64;
371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- "CUConst" structure                                  ---*/
377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
380746e97e7098def65d59c79d5d661f9a757a837cdphilippetypedef
381746e97e7098def65d59c79d5d661f9a757a837cdphilippe   struct _name_form {
382746e97e7098def65d59c79d5d661f9a757a837cdphilippe      ULong at_name;
383746e97e7098def65d59c79d5d661f9a757a837cdphilippe      ULong at_form;
384746e97e7098def65d59c79d5d661f9a757a837cdphilippe   } name_form;
385746e97e7098def65d59c79d5d661f9a757a837cdphilippe
386746e97e7098def65d59c79d5d661f9a757a837cdphilippetypedef
387746e97e7098def65d59c79d5d661f9a757a837cdphilippe   struct _g_abbv {
388746e97e7098def65d59c79d5d661f9a757a837cdphilippe      struct _g_abbv *next; // read/write by hash table.
389746e97e7098def65d59c79d5d661f9a757a837cdphilippe      UWord  abbv_code;     // key, read by hash table
390746e97e7098def65d59c79d5d661f9a757a837cdphilippe      ULong  atag;
391746e97e7098def65d59c79d5d661f9a757a837cdphilippe      ULong  has_children;
392746e97e7098def65d59c79d5d661f9a757a837cdphilippe      name_form nf[0];
393746e97e7098def65d59c79d5d661f9a757a837cdphilippe      /* Variable-length array of name/form pairs, terminated
394746e97e7098def65d59c79d5d661f9a757a837cdphilippe         by a 0/0 pair. */
395746e97e7098def65d59c79d5d661f9a757a837cdphilippe    } g_abbv;
396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
397b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Holds information that is constant through the parsing of a
398b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Compilation Unit.  This is basically plumbed through to
399b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   everywhere. */
400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct {
402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Call here if anything goes wrong */
4036bd9dc18c043927c1196caba20a327238a179c42florian      void (*barf)( const HChar* ) __attribute__((noreturn));
404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Is this 64-bit DWARF ? */
405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   is_dw64;
406fba428cd266b8a39db641c5fd9523daa8939bed0tom      /* Which DWARF version ?  (2, 3 or 4) */
407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UShort version;
408055b0f85aaa42477a803d445885c389561d3d3c8sewardj      /* Length of this Compilation Unit, as stated in the
409055b0f85aaa42477a803d445885c389561d3d3c8sewardj         .unit_length :: InitialLength field of the CU Header.
410055b0f85aaa42477a803d445885c389561d3d3c8sewardj         However, this size (as specified by the D3 spec) does not
411055b0f85aaa42477a803d445885c389561d3d3c8sewardj         include the size of the .unit_length field itself, which is
412055b0f85aaa42477a803d445885c389561d3d3c8sewardj         either 4 or 12 bytes (32-bit or 64-bit Dwarf3).  That value
413055b0f85aaa42477a803d445885c389561d3d3c8sewardj         can be obtained through the expression ".is_dw64 ? 12 : 4". */
414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ULong  unit_length;
415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Offset of start of this unit in .debug_info */
416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord  cu_start_offset;
417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* SVMA for this CU.  In the D3 spec, is known as the "base
418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         address of the compilation unit (last para sec 3.1.1).
419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Needed for (amongst things) interpretation of location-list
420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         values. */
421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr   cu_svma;
422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   cu_svma_known;
4235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* The debug_abbreviations table to be used for this Unit */
4255d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      //UChar* debug_abbv;
426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Upper bound on size thereof (an overestimate, in general) */
4275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      //UWord  debug_abbv_maxszB;
4285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      /* A bounded area of the image, to be used as the
4295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         debug_abbreviations table tobe used for this Unit. */
4305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice debug_abbv;
4315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
4325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      /* Image information for various sections. */
4335d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_str;
4345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_ranges;
4355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_loc;
4365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_line;
4375d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_info;
4385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_types;
4395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_info_alt;
4405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_str_alt;
441f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      /* How much to add to .debug_types resp. alternate .debug_info offsets
442f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         in cook_die*.  */
443f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      UWord  types_cuOff_bias;
444f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      UWord  alt_cuOff_bias;
445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* --- Needed so we can add stuff to the string table. --- */
446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      struct _DebugInfo* di;
447746e97e7098def65d59c79d5d661f9a757a837cdphilippe      /* --- a hash table of g_abbv (i.e. parsed abbreviations) --- */
448746e97e7098def65d59c79d5d661f9a757a837cdphilippe      VgHashTable ht_abbvs;
449d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
450d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      /* True if this came from .debug_types; otherwise it came from
451d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         .debug_info.  */
452d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      Bool is_type_unit;
453d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      /* For a unit coming from .debug_types, these hold the TU's type
454d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         signature and the uncooked DIE offset of the TU's signatured
455d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         type.  For a unit coming from .debug_info, these are unused.  */
456d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      ULong type_signature;
457d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      ULong type_offset;
458d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
459d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      /* Signatured type hash; computed once and then shared by all
460d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         CUs.  */
461d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      VgHashTable signature_types;
462f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj
463f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      /* True if this came from alternate .debug_info; otherwise
464f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         it came from normal .debug_info or .debug_types.  */
465f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      Bool is_alt_info;
466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   CUConst;
468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
470d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj/* Return the cooked value of DIE depending on whether CC represents a
471f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   .debug_types unit.  To cook a DIE, we pretend that the .debug_info,
472f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   .debug_types and optional alternate .debug_info sections form
473f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   a contiguous whole, so that DIEs coming from .debug_types are numbered
474f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   starting at the end of .debug_info and DIEs coming from alternate
475f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   .debug_info are numbered starting at the end of .debug_types.  */
476d935068fc7b53c8a826b3436cdfccd5b7d446903sewardjstatic UWord cook_die( CUConst* cc, UWord die )
477d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj{
478d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   if (cc->is_type_unit)
479f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      die += cc->types_cuOff_bias;
480f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   else if (cc->is_alt_info)
481f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      die += cc->alt_cuOff_bias;
482d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   return die;
483d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj}
484d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
485d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj/* Like cook_die, but understand that DIEs coming from a
486f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   DW_FORM_ref_sig8 reference are already cooked.  Also, handle
487f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   DW_FORM_GNU_ref_alt from within primary .debug_info or .debug_types
488f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   as reference to alternate .debug_info.  */
489d935068fc7b53c8a826b3436cdfccd5b7d446903sewardjstatic UWord cook_die_using_form( CUConst *cc, UWord die, DW_FORM form)
490d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj{
491d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   if (form == DW_FORM_ref_sig8)
492d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      return die;
493f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   if (form == DW_FORM_GNU_ref_alt)
494f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      return die + cc->alt_cuOff_bias;
495d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   return cook_die( cc, die );
496d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj}
497d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
498f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj/* Return the uncooked offset of DIE and set *TYPE_FLAG to true if the DIE
499f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   came from the .debug_types section and *ALT_FLAG to true if the DIE
500f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   came from alternate .debug_info section.  */
501f7c9714ea0cde18daaecb896278e85e780d3bd75sewardjstatic UWord uncook_die( CUConst *cc, UWord die, /*OUT*/Bool *type_flag,
502f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                         Bool *alt_flag )
503d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj{
504f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   *alt_flag = False;
505f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   *type_flag = False;
5065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   /* The use of escn_debug_{info,types}.szB seems safe to me even if
5075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      escn_debug_{info,types} are DiSlice_INVALID (meaning the
5085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      sections were not found), because DiSlice_INVALID.szB is always
5095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      zero.  That said, it seems unlikely we'd ever get here if
5105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      .debug_info or .debug_types were missing. */
5115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (die >= cc->escn_debug_info.szB) {
5125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      if (die >= cc->escn_debug_info.szB + cc->escn_debug_types.szB) {
513f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         *alt_flag = True;
5145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         die -= cc->escn_debug_info.szB + cc->escn_debug_types.szB;
515f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      } else {
516f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         *type_flag = True;
5175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         die -= cc->escn_debug_info.szB;
518f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      }
519d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   }
520d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   return die;
521d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj}
522d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Helper functions for Guarded Expressions             ---*/
526b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
527b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
528b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
529b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Parse the location list starting at img-offset 'debug_loc_offset'
530b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   in .debug_loc.  Results are biased with 'svma_of_referencing_CU'
531b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   and so I believe are correct SVMAs for the object as a whole.  This
532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   function allocates the UChar*, and the caller must deallocate it.
533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   The resulting block is in so-called Guarded-Expression format.
534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Guarded-Expression format is similar but not identical to the DWARF3
536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   location-list format.  The format of each returned block is:
537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar biasMe;
539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar isEnd;
540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      followed by zero or more of
541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      (Addr aMin;  Addr aMax;  UShort nbytes;  ..bytes..;  UChar isEnd)
543b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   '..bytes..' is an standard DWARF3 location expression which is
545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   valid when aMin <= pc <= aMax (possibly after suitable biasing).
546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   The number of bytes in '..bytes..' is nbytes.
548b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
549b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   The end of the sequence is marked by an isEnd == 1 value.  All
550b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   previous isEnd values must be zero.
551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   biasMe is 1 if the aMin/aMax fields need this DebugInfo's
553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   text_bias added before use, and 0 if the GX is this is not
554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   necessary (is ready to go).
555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Hence the block can be quickly parsed and is self-describing.  Note
557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   that aMax is 1 less than the corresponding value in a DWARF3
558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   location list.  Zero length ranges, with aMax == aMin-1, are not
559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   allowed.
560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/
5619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* 2008-sept-12: moved ML_(pp_GX) from here to d3basics.c, where
5629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   it more logically belongs. */
5639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
565402c9eed11b9b60c6e134d05db938e395466cf99tom/* Apply a text bias to a GX. */
566402c9eed11b9b60c6e134d05db938e395466cf99tomstatic void bias_GX ( /*MOD*/GExpr* gx, struct _DebugInfo* di )
567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UShort nbytes;
569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar* p = &gx->payload[0];
57086781fabbfc019b752f9605e487cfce77b2a592atom   UChar* pA;
571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar  uc;
572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   uc = *p++; /*biasMe*/
573b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (uc == 0)
574b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return;
575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(uc == 1);
576b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   p[-1] = 0; /* mark it as done */
577b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
578b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      uc = *p++;
579b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (uc == 1)
580b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break; /*isEnd*/
581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(uc == 0);
58268a2ebd9384661a85a4674fe8310c595ad494305sewardj      /* t-bias aMin */
58386781fabbfc019b752f9605e487cfce77b2a592atom      pA = (UChar*)p;
58486781fabbfc019b752f9605e487cfce77b2a592atom      ML_(write_Addr)(pA, ML_(read_Addr)(pA) + di->text_debug_bias);
58568a2ebd9384661a85a4674fe8310c595ad494305sewardj      p += sizeof(Addr);
58668a2ebd9384661a85a4674fe8310c595ad494305sewardj      /* t-bias aMax */
58786781fabbfc019b752f9605e487cfce77b2a592atom      pA = (UChar*)p;
58886781fabbfc019b752f9605e487cfce77b2a592atom      ML_(write_Addr)(pA, ML_(read_Addr)(pA) + di->text_debug_bias);
58968a2ebd9384661a85a4674fe8310c595ad494305sewardj      p += sizeof(Addr);
59068a2ebd9384661a85a4674fe8310c595ad494305sewardj      /* nbytes, and actual expression */
59186781fabbfc019b752f9605e487cfce77b2a592atom      nbytes = ML_(read_UShort)(p); p += sizeof(UShort);
592b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      p += nbytes;
593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
594b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
595b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
596b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
5975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic GExpr* make_singleton_GX ( DiCursor block, ULong nbytes )
598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   SizeT  bytesReqd;
600b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   GExpr* gx;
601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar *p, *pstart;
602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(sizeof(UWord) == sizeof(Addr));
604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(nbytes <= 0xFFFF); /* else we overflow the nbytes field */
605b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bytesReqd
606b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      =   sizeof(UChar)  /*biasMe*/    + sizeof(UChar) /*!isEnd*/
607b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        + sizeof(UWord)  /*aMin*/      + sizeof(UWord) /*aMax*/
6085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj        + sizeof(UShort) /*nbytes*/    + (SizeT)nbytes
609b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        + sizeof(UChar); /*isEnd*/
610b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   gx = ML_(dinfo_zalloc)( "di.readdwarf3.msGX.1",
6129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                           sizeof(GExpr) + bytesReqd );
613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(gx);
614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   p = pstart = &gx->payload[0];
616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
61786781fabbfc019b752f9605e487cfce77b2a592atom   p = ML_(write_UChar)(p, 0);        /*biasMe*/
61886781fabbfc019b752f9605e487cfce77b2a592atom   p = ML_(write_UChar)(p, 0);        /*!isEnd*/
61986781fabbfc019b752f9605e487cfce77b2a592atom   p = ML_(write_Addr)(p, 0);         /*aMin*/
62086781fabbfc019b752f9605e487cfce77b2a592atom   p = ML_(write_Addr)(p, ~0);        /*aMax*/
62186781fabbfc019b752f9605e487cfce77b2a592atom   p = ML_(write_UShort)(p, nbytes);  /*nbytes*/
6225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   ML_(cur_read_get)(p, block, nbytes); p += nbytes;
62386781fabbfc019b752f9605e487cfce77b2a592atom   p = ML_(write_UChar)(p, 1);        /*isEnd*/
624b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert( (SizeT)(p - pstart) == bytesReqd);
626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert( &gx->payload[bytesReqd]
627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              == ((UChar*)gx) + sizeof(GExpr) + bytesReqd );
628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return gx;
630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic GExpr* make_general_GX ( CUConst* cc,
634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                Bool     td3,
6355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                ULong    debug_loc_offset,
636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                Addr     svma_of_referencing_CU )
637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Addr      base;
639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Cursor    loc;
640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   XArray*   xa; /* XArray of UChar */
641b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   GExpr*    gx;
642b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Word      nbytes;
643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
644b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(sizeof(UWord) == sizeof(Addr));
6455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (!ML_(sli_is_valid)(cc->escn_debug_loc) || cc->escn_debug_loc.szB == 0)
646b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("make_general_GX: .debug_loc is empty/missing");
647b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   init_Cursor( &loc, cc->escn_debug_loc, 0, cc->barf,
649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                "Overrun whilst reading .debug_loc section(2)" );
650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   set_position_of_Cursor( &loc, debug_loc_offset );
651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   TRACE_D3("make_general_GX (.debug_loc_offset = %llu, ioff = %llu) {\n",
6535d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            debug_loc_offset, (ULong)get_DiCursor_from_Cursor(&loc).ioff );
654b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
655b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Who frees this xa?  It is freed before this fn exits. */
6569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.mgGX.1",
6579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                    ML_(dinfo_free),
658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    sizeof(UChar) );
659b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   { UChar c = 1; /*biasMe*/ VG_(addBytesToXA)( xa, &c, sizeof(c) ); }
661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   base = 0;
663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
664b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool  acquire;
665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord len;
666b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Read a (host-)word pair.  This is something of a hack since
667b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         the word size to read is really dictated by the ELF file;
668b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         however, we assume we're reading a file with the same
669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         word-sizeness as the host.  Reasonably enough. */
670b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord w1 = get_UWord( &loc );
671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord w2 = get_UWord( &loc );
672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("   %08lx %08lx\n", w1, w2);
674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 == 0 && w2 == 0)
675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break; /* end of list */
676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 == -1UL) {
678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* new value for 'base' */
679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         base = w2;
680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         continue;
681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* else a location expression follows */
684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* else enumerate [w1+base, w2+base) */
685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* w2 is 1 past end of range, as per D3 defn for "DW_AT_high_pc"
686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (sec 2.17.2) */
687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 > w2) {
688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("negative range is for .debug_loc expr at "
6895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  "file offset %llu\n",
690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  debug_loc_offset);
691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         cc->barf( "negative range in .debug_loc section" );
692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* ignore zero length ranges */
695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      acquire = w1 < w2;
696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      len     = (UWord)get_UShort( &loc );
697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (acquire) {
699b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UWord  w;
700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UShort s;
701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UChar  c;
702b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         c = 0; /* !isEnd*/
703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(addBytesToXA)( xa, &c, sizeof(c) );
704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         w = w1    + base + svma_of_referencing_CU;
705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(addBytesToXA)( xa, &w, sizeof(w) );
706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         w = w2 -1 + base + svma_of_referencing_CU;
707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(addBytesToXA)( xa, &w, sizeof(w) );
708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s = (UShort)len;
709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(addBytesToXA)( xa, &s, sizeof(s) );
710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (len > 0) {
713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UChar byte = get_UChar( &loc );
714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("%02x", (UInt)byte);
715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (acquire)
716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            VG_(addBytesToXA)( xa, &byte, 1 );
717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         len--;
718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("\n");
720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   { UChar c = 1; /*isEnd*/ VG_(addBytesToXA)( xa, &c, sizeof(c) ); }
723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   nbytes = VG_(sizeXA)( xa );
725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(nbytes >= 1);
726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
7279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   gx = ML_(dinfo_zalloc)( "di.readdwarf3.mgGX.2", sizeof(GExpr) + nbytes );
728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(gx);
729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(memcpy)( &gx->payload[0], (UChar*)VG_(indexXA)(xa,0), nbytes );
730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert( &gx->payload[nbytes]
731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              == ((UChar*)gx) + sizeof(GExpr) + nbytes );
732b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(deleteXA)( xa );
734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3("}\n");
736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return gx;
738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
742b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
743b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Helper functions for range lists and CU headers      ---*/
744b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
745b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
746b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
747b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Denotes an address range.  Both aMin and aMax are included in the
748b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   range; hence a complete range is (0, ~0) and an empty range is any
749b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   (X, X-1) for X > 0.*/
750b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
751b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct { Addr aMin; Addr aMax; }
752b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   AddrRange;
753b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
754b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
7559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Generate an arbitrary structural total ordering on
7569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   XArray* of AddrRange. */
7579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic Word cmp__XArrays_of_AddrRange ( XArray* rngs1, XArray* rngs2 )
7589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
7599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Word n1, n2, i;
7609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   tl_assert(rngs1 && rngs2);
7619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   n1 = VG_(sizeXA)( rngs1 );
7629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   n2 = VG_(sizeXA)( rngs2 );
7639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (n1 < n2) return -1;
7649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (n1 > n2) return 1;
7659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   for (i = 0; i < n1; i++) {
7669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      AddrRange* rng1 = (AddrRange*)VG_(indexXA)( rngs1, i );
7679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      AddrRange* rng2 = (AddrRange*)VG_(indexXA)( rngs2, i );
7689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (rng1->aMin < rng2->aMin) return -1;
7699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (rng1->aMin > rng2->aMin) return 1;
7709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (rng1->aMax < rng2->aMax) return -1;
7719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (rng1->aMax > rng2->aMax) return 1;
7729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
7739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   return 0;
7749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj}
7759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
7769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
777b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic XArray* /* of AddrRange */ empty_range_list ( void )
779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   XArray* xa; /* XArray of AddrRange */
781b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Who frees this xa?  varstack_preen() does. */
7829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.erl.1",
7839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                    ML_(dinfo_free),
784b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    sizeof(AddrRange) );
785b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return xa;
786b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
787b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
7899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj__attribute__((noinline))
790b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic XArray* unitary_range_list ( Addr aMin, Addr aMax )
791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   XArray*   xa;
793b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   AddrRange pair;
794b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(aMin <= aMax);
795b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Who frees this xa?  varstack_preen() does. */
7969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   xa = VG_(newXA)( ML_(dinfo_zalloc),  "di.readdwarf3.url.1",
7979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                    ML_(dinfo_free),
798b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    sizeof(AddrRange) );
799b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   pair.aMin = aMin;
800b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   pair.aMax = aMax;
801b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(addToXA)( xa, &pair );
802b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return xa;
803b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
804b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
805b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
806b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Enumerate the address ranges starting at img-offset
807b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   'debug_ranges_offset' in .debug_ranges.  Results are biased with
808b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   'svma_of_referencing_CU' and so I believe are correct SVMAs for the
809b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   object as a whole.  This function allocates the XArray, and the
810b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   caller must deallocate it. */
811b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
812b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic XArray* /* of AddrRange */
813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       get_range_list ( CUConst* cc,
814b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        Bool     td3,
815b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        UWord    debug_ranges_offset,
816b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        Addr     svma_of_referencing_CU )
817b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
818b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Addr      base;
819b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Cursor    ranges;
820b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   XArray*   xa; /* XArray of AddrRange */
821b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   AddrRange pair;
822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
8235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (!ML_(sli_is_valid)(cc->escn_debug_ranges)
8245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj       || cc->escn_debug_ranges.szB == 0)
825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("get_range_list: .debug_ranges is empty/missing");
826b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
8275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   init_Cursor( &ranges, cc->escn_debug_ranges, 0, cc->barf,
828b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                "Overrun whilst reading .debug_ranges section(2)" );
829b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   set_position_of_Cursor( &ranges, debug_ranges_offset );
830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Who frees this xa?  varstack_preen() does. */
8329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.grl.1", ML_(dinfo_free),
833b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    sizeof(AddrRange) );
834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   base = 0;
835b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
836b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Read a (host-)word pair.  This is something of a hack since
837b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         the word size to read is really dictated by the ELF file;
838b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         however, we assume we're reading a file with the same
839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         word-sizeness as the host.  Reasonably enough. */
840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord w1 = get_UWord( &ranges );
841b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord w2 = get_UWord( &ranges );
842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 == 0 && w2 == 0)
844b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break; /* end of list. */
845b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
846b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 == -1UL) {
847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* new value for 'base' */
848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         base = w2;
849b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         continue;
850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
851b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* else enumerate [w1+base, w2+base) */
853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* w2 is 1 past end of range, as per D3 defn for "DW_AT_high_pc"
854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (sec 2.17.2) */
855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 > w2)
856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         cc->barf( "negative range in .debug_ranges section" );
857b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 < w2) {
858b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         pair.aMin = w1     + base + svma_of_referencing_CU;
859b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         pair.aMax = w2 - 1 + base + svma_of_referencing_CU;
860b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vg_assert(pair.aMin <= pair.aMax);
861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(addToXA)( xa, &pair );
862b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
863b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
864b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return xa;
865b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
866b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
867746e97e7098def65d59c79d5d661f9a757a837cdphilippe/* Initialises the hash table of abbreviations.
868746e97e7098def65d59c79d5d661f9a757a837cdphilippe   We do a single scan of the abbv slice to parse and
869746e97e7098def65d59c79d5d661f9a757a837cdphilippe   build all abbreviations, for the following reasons:
870746e97e7098def65d59c79d5d661f9a757a837cdphilippe     * all or most abbreviations will be needed in any case
871746e97e7098def65d59c79d5d661f9a757a837cdphilippe       (at least for var-info reading).
872746e97e7098def65d59c79d5d661f9a757a837cdphilippe     * re-reading each time an abbreviation causes a lot of calls
873746e97e7098def65d59c79d5d661f9a757a837cdphilippe       to get_ULEB128.
874746e97e7098def65d59c79d5d661f9a757a837cdphilippe     * a CU should not have many abbreviations. */
875746e97e7098def65d59c79d5d661f9a757a837cdphilippestatic void init_ht_abbvs (CUConst* cc,
876746e97e7098def65d59c79d5d661f9a757a837cdphilippe                           Bool td3)
877746e97e7098def65d59c79d5d661f9a757a837cdphilippe{
878746e97e7098def65d59c79d5d661f9a757a837cdphilippe   Cursor c;
879746e97e7098def65d59c79d5d661f9a757a837cdphilippe   g_abbv *ta; // temporary abbreviation, reallocated if needed.
880746e97e7098def65d59c79d5d661f9a757a837cdphilippe   UInt ta_nf_maxE; // max nr of pairs in ta.nf[], doubled when reallocated.
881746e97e7098def65d59c79d5d661f9a757a837cdphilippe   UInt ta_nf_n;    // nr of pairs in ta->nf that are initialised.
882746e97e7098def65d59c79d5d661f9a757a837cdphilippe   g_abbv *ht_ta; // abbv to insert in hash table.
883746e97e7098def65d59c79d5d661f9a757a837cdphilippe
884746e97e7098def65d59c79d5d661f9a757a837cdphilippe   #define SZ_G_ABBV(_nf_szE) (sizeof(g_abbv) + _nf_szE * sizeof(name_form))
885746e97e7098def65d59c79d5d661f9a757a837cdphilippe
886746e97e7098def65d59c79d5d661f9a757a837cdphilippe   ta_nf_maxE = 10; // starting with enough for 9 pairs+terminating pair.
887746e97e7098def65d59c79d5d661f9a757a837cdphilippe   ta = ML_(dinfo_zalloc) ("di.readdwarf3.ht_ta_nf", SZ_G_ABBV(ta_nf_maxE));
888746e97e7098def65d59c79d5d661f9a757a837cdphilippe   cc->ht_abbvs = VG_(HT_construct) ("di.readdwarf3.ht_abbvs");
889746e97e7098def65d59c79d5d661f9a757a837cdphilippe
890746e97e7098def65d59c79d5d661f9a757a837cdphilippe   init_Cursor( &c, cc->debug_abbv, 0, cc->barf,
891746e97e7098def65d59c79d5d661f9a757a837cdphilippe               "Overrun whilst parsing .debug_abbrev section(2)" );
892746e97e7098def65d59c79d5d661f9a757a837cdphilippe   while (True) {
893746e97e7098def65d59c79d5d661f9a757a837cdphilippe      ta->abbv_code = get_ULEB128( &c );
894746e97e7098def65d59c79d5d661f9a757a837cdphilippe      if (ta->abbv_code == 0) break; /* end of the table */
895746e97e7098def65d59c79d5d661f9a757a837cdphilippe
896746e97e7098def65d59c79d5d661f9a757a837cdphilippe      ta->atag = get_ULEB128( &c );
897746e97e7098def65d59c79d5d661f9a757a837cdphilippe      ta->has_children = get_UChar( &c );
898746e97e7098def65d59c79d5d661f9a757a837cdphilippe      ta_nf_n = 0;
899746e97e7098def65d59c79d5d661f9a757a837cdphilippe      while (True) {
900746e97e7098def65d59c79d5d661f9a757a837cdphilippe         if (ta_nf_n >= ta_nf_maxE) {
901746e97e7098def65d59c79d5d661f9a757a837cdphilippe            g_abbv *old_ta = ta;
902746e97e7098def65d59c79d5d661f9a757a837cdphilippe            ta = ML_(dinfo_zalloc) ("di.readdwarf3.ht_ta_nf",
903746e97e7098def65d59c79d5d661f9a757a837cdphilippe                                    SZ_G_ABBV(2 * ta_nf_maxE));
904746e97e7098def65d59c79d5d661f9a757a837cdphilippe            ta_nf_maxE = 2 * ta_nf_maxE;
905746e97e7098def65d59c79d5d661f9a757a837cdphilippe            VG_(memcpy) (ta, old_ta, SZ_G_ABBV(ta_nf_n));
906746e97e7098def65d59c79d5d661f9a757a837cdphilippe            ML_(dinfo_free) (old_ta);
907746e97e7098def65d59c79d5d661f9a757a837cdphilippe         }
908746e97e7098def65d59c79d5d661f9a757a837cdphilippe         ta->nf[ta_nf_n].at_name = get_ULEB128( &c );
909746e97e7098def65d59c79d5d661f9a757a837cdphilippe         ta->nf[ta_nf_n].at_form = get_ULEB128( &c );
910746e97e7098def65d59c79d5d661f9a757a837cdphilippe         if (ta->nf[ta_nf_n].at_name == 0 && ta->nf[ta_nf_n].at_form == 0) {
911746e97e7098def65d59c79d5d661f9a757a837cdphilippe            ta_nf_n++;
912746e97e7098def65d59c79d5d661f9a757a837cdphilippe            break;
913746e97e7098def65d59c79d5d661f9a757a837cdphilippe         }
914746e97e7098def65d59c79d5d661f9a757a837cdphilippe        ta_nf_n++;
915746e97e7098def65d59c79d5d661f9a757a837cdphilippe      }
916746e97e7098def65d59c79d5d661f9a757a837cdphilippe      ht_ta = ML_(dinfo_zalloc) ("di.readdwarf3.ht_ta", SZ_G_ABBV(ta_nf_n));
917746e97e7098def65d59c79d5d661f9a757a837cdphilippe      VG_(memcpy) (ht_ta, ta, SZ_G_ABBV(ta_nf_n));
918746e97e7098def65d59c79d5d661f9a757a837cdphilippe      VG_(HT_add_node) ( cc->ht_abbvs, ht_ta );
919746e97e7098def65d59c79d5d661f9a757a837cdphilippe      TRACE_D3("  Adding abbv_code %llu TAG  %s [%s] nf %d\n",
920746e97e7098def65d59c79d5d661f9a757a837cdphilippe               (ULong) ht_ta->abbv_code, ML_(pp_DW_TAG)(ht_ta->atag),
921746e97e7098def65d59c79d5d661f9a757a837cdphilippe               ML_(pp_DW_children)(ht_ta->has_children),
922746e97e7098def65d59c79d5d661f9a757a837cdphilippe               ta_nf_n);
923746e97e7098def65d59c79d5d661f9a757a837cdphilippe   }
924746e97e7098def65d59c79d5d661f9a757a837cdphilippe
925746e97e7098def65d59c79d5d661f9a757a837cdphilippe   ML_(dinfo_free) (ta);
926746e97e7098def65d59c79d5d661f9a757a837cdphilippe   #undef SZ_G_ABBV
927746e97e7098def65d59c79d5d661f9a757a837cdphilippe}
928746e97e7098def65d59c79d5d661f9a757a837cdphilippe
929746e97e7098def65d59c79d5d661f9a757a837cdphilippestatic g_abbv* get_abbv (CUConst* cc, ULong abbv_code)
930746e97e7098def65d59c79d5d661f9a757a837cdphilippe{
931746e97e7098def65d59c79d5d661f9a757a837cdphilippe   g_abbv *abbv;
932746e97e7098def65d59c79d5d661f9a757a837cdphilippe
933746e97e7098def65d59c79d5d661f9a757a837cdphilippe   abbv = VG_(HT_lookup) (cc->ht_abbvs, abbv_code);
934746e97e7098def65d59c79d5d661f9a757a837cdphilippe   if (!abbv)
935746e97e7098def65d59c79d5d661f9a757a837cdphilippe      cc->barf ("abbv_code not found in ht_abbvs table");
936746e97e7098def65d59c79d5d661f9a757a837cdphilippe   return abbv;
937746e97e7098def65d59c79d5d661f9a757a837cdphilippe}
938746e97e7098def65d59c79d5d661f9a757a837cdphilippe
939746e97e7098def65d59c79d5d661f9a757a837cdphilippe/* Free the memory allocated in CUConst. */
940746e97e7098def65d59c79d5d661f9a757a837cdphilippestatic void clear_CUConst (CUConst* cc)
941746e97e7098def65d59c79d5d661f9a757a837cdphilippe{
942746e97e7098def65d59c79d5d661f9a757a837cdphilippe   VG_(HT_destruct) ( cc->ht_abbvs, ML_(dinfo_free));
943746e97e7098def65d59c79d5d661f9a757a837cdphilippe   cc->ht_abbvs = NULL;
944746e97e7098def65d59c79d5d661f9a757a837cdphilippe}
945b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
946b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Parse the Compilation Unit header indicated at 'c' and
947b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   initialise 'cc' accordingly. */
948b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic __attribute__((noinline))
949b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid parse_CU_Header ( /*OUT*/CUConst* cc,
950b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                       Bool td3,
951b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                       Cursor* c,
9525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                       DiSlice escn_debug_abbv,
953f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj		       Bool type_unit,
954f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                       Bool alt_info )
955b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
956b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar  address_size;
9575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   ULong  debug_abbrev_offset;
958b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
959b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(memset)(cc, 0, sizeof(*cc));
960b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(c && c->barf);
961b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   cc->barf = c->barf;
962b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
963b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* initial_length field */
964b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   cc->unit_length
965b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      = get_Initial_Length( &cc->is_dw64, c,
966b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           "parse_CU_Header: invalid initial-length field" );
967b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
968b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3("   Length:        %lld\n", cc->unit_length );
969b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
970b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* version */
971b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   cc->version = get_UShort( c );
972fba428cd266b8a39db641c5fd9523daa8939bed0tom   if (cc->version != 2 && cc->version != 3 && cc->version != 4)
973fba428cd266b8a39db641c5fd9523daa8939bed0tom      cc->barf( "parse_CU_Header: is neither DWARF2 nor DWARF3 nor DWARF4" );
974b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3("   Version:       %d\n", (Int)cc->version );
975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
976b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* debug_abbrev_offset */
977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   debug_abbrev_offset = get_Dwarfish_UWord( c, cc->is_dw64 );
9785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (debug_abbrev_offset >= escn_debug_abbv.szB)
979b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf( "parse_CU_Header: invalid debug_abbrev_offset" );
9805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   TRACE_D3("   Abbrev Offset: %lld\n", debug_abbrev_offset );
981b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
982b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* address size.  If this isn't equal to the host word size, just
983b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      give up.  This makes it safe to assume elsewhere that
98431452303b095a76295b08096b2840276db808b81sewardj      DW_FORM_addr and DW_FORM_ref_addr can be treated as a host
98531452303b095a76295b08096b2840276db808b81sewardj      word. */
986b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   address_size = get_UChar( c );
987b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (address_size != sizeof(void*))
988b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf( "parse_CU_Header: invalid address_size" );
989b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3("   Pointer Size:  %d\n", (Int)address_size );
990b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
991d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   cc->is_type_unit = type_unit;
992f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   cc->is_alt_info = alt_info;
993d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
994d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   if (type_unit) {
995d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      cc->type_signature = get_ULong( c );
996d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      cc->type_offset = get_Dwarfish_UWord( c, cc->is_dw64 );
997d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   }
998d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
9995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   /* Set up cc->debug_abbv to point to the relevant table for this
10005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      CU.  Set its .szB so that at least we can't read off the end of
10015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      the debug_abbrev section -- potentially (and quite likely) too
10025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      big, if this isn't the last table in the section, but at least
10035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      it's safe.
10045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
10055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      This amounts to taking debug_abbv_escn and moving the start
10065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      position along by debug_abbrev_offset bytes, hence forming a
10075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      smaller DiSlice which has the same end point.  Since we checked
10085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      just above that debug_abbrev_offset is less than the size of
10095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      debug_abbv_escn, this should leave us with a nonempty slice. */
10105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   vg_assert(debug_abbrev_offset < escn_debug_abbv.szB);
10115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   cc->debug_abbv      = escn_debug_abbv;
10125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   cc->debug_abbv.ioff += debug_abbrev_offset;
10135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   cc->debug_abbv.szB  -= debug_abbrev_offset;
10145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1015746e97e7098def65d59c79d5d661f9a757a837cdphilippe   init_ht_abbvs(cc, td3);
1016b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1018d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj/* This represents a single signatured type.  It maps a type signature
1019d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   (a ULong) to a cooked DIE offset.  Objects of this type are stored
1020d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   in the type signature hash table.  */
1021d935068fc7b53c8a826b3436cdfccd5b7d446903sewardjtypedef
1022d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   struct D3SignatureType {
1023d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      struct D3SignatureType *next;
1024d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      UWord data;
1025d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      ULong type_signature;
1026d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      UWord die;
1027d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   }
1028d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   D3SignatureType;
1029d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
1030d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj/* Record a signatured type in the hash table.  */
1031d935068fc7b53c8a826b3436cdfccd5b7d446903sewardjstatic void record_signatured_type ( VgHashTable tab,
1032d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                                     ULong type_signature,
1033d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                                     UWord die )
1034d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj{
1035d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   D3SignatureType *dstype = ML_(dinfo_zalloc) ( "di.readdwarf3.sigtype",
1036d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                                                 sizeof(D3SignatureType) );
1037d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   dstype->data = (UWord) type_signature;
1038d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   dstype->type_signature = type_signature;
1039d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   dstype->die = die;
1040d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   VG_(HT_add_node) ( tab, dstype );
1041d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj}
1042d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
1043d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj/* Given a type signature hash table and a type signature, return the
1044d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   cooked DIE offset of the type.  If the type cannot be found, call
1045d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   BARF.  */
1046d935068fc7b53c8a826b3436cdfccd5b7d446903sewardjstatic UWord lookup_signatured_type ( VgHashTable tab,
1047d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                                      ULong type_signature,
10486bd9dc18c043927c1196caba20a327238a179c42florian                                      void (*barf)( const HChar* ) __attribute__((noreturn)) )
1049d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj{
1050d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   D3SignatureType *dstype = VG_(HT_lookup) ( tab, (UWord) type_signature );
1051d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   /* This may be unwarranted chumminess with the hash table
1052d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      implementation.  */
1053d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   while ( dstype != NULL && dstype->type_signature != type_signature)
1054d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      dstype = dstype->next;
1055d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   if (dstype == NULL) {
1056d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      barf("lookup_signatured_type: could not find signatured type");
1057d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      /*NOTREACHED*/
1058d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      vg_assert(0);
1059d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   }
1060d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   return dstype->die;
1061d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj}
1062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
10645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Represents Form data.  If szB is 1/2/4/8 then the result is in the
10655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   lowest 1/2/4/8 bytes of u.val.  If szB is zero or negative then the
10665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   result is an image section beginning at u.cur and with size -szB.
10675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   No other szB values are allowed. */
10685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjtypedef
10695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   struct {
10705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      Long szB; // 1, 2, 4, 8 or non-positive values only.
10715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      union { ULong val; DiCursor cur; } u;
10725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   }
10735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   FormContents;
1074b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
10755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* From 'c', get the Form data into 'cts'.  Either it gets a 1/2/4/8
10765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   byte scalar value, or (a reference to) zero or more bytes starting
10775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   at a DiCursor.*/
1078b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
10795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjvoid get_Form_contents ( /*OUT*/FormContents* cts,
1080b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                         CUConst* cc, Cursor* c,
1081b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                         Bool td3, DW_FORM form )
1082b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
10835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   VG_(bzero_inline)(cts, sizeof(*cts));
1084b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   switch (form) {
1085b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_data1:
10865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)(UChar)get_UChar(c);
10875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 1;
10885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%u", (UInt)cts->u.val);
1089b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1090b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_data2:
10915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)(UShort)get_UShort(c);
10925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 2;
10935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%u", (UInt)cts->u.val);
1094b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1095b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_data4:
10965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)(UInt)get_UInt(c);
10975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 4;
10985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%u", (UInt)cts->u.val);
1099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
11000b5bf911d9d40b8dd3130f6043ef7ba68a9f446esewardj      case DW_FORM_data8:
11015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = get_ULong(c);
11025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 8;
11035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%llu", cts->u.val);
11040b5bf911d9d40b8dd3130f6043ef7ba68a9f446esewardj         break;
1105fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_sec_offset:
11065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)get_Dwarfish_UWord( c, cc->is_dw64 );
11075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = cc->is_dw64 ? 8 : 4;
11085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%llu", cts->u.val);
1109fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_sdata:
11115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)(Long)get_SLEB128(c);
11125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 8;
11135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%lld", (Long)cts->u.val);
1114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1115fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_udata:
11165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)(Long)get_ULEB128(c);
11175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 8;
11185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%llu", (Long)cts->u.val);
1119fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_addr:
1121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* note, this is a hack.  DW_FORM_addr is defined as getting
1122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            a word the size of the target machine as defined by the
1123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            address_size field in the CU Header.  However,
1124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            parse_CU_Header() rejects all inputs except those for
1125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            which address_size == sizeof(Word), hence we can just
1126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            treat it as a (host) Word.  */
11275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)(UWord)get_UWord(c);
11285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
11295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("0x%lx", (UWord)cts->u.val);
1130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
113131452303b095a76295b08096b2840276db808b81sewardj
113231452303b095a76295b08096b2840276db808b81sewardj      case DW_FORM_ref_addr:
113331452303b095a76295b08096b2840276db808b81sewardj         /* We make the same word-size assumption as DW_FORM_addr. */
113431452303b095a76295b08096b2840276db808b81sewardj         /* What does this really mean?  From D3 Sec 7.5.4,
113531452303b095a76295b08096b2840276db808b81sewardj            description of "reference", it would appear to reference
113631452303b095a76295b08096b2840276db808b81sewardj            some other DIE, by specifying the offset from the
113731452303b095a76295b08096b2840276db808b81sewardj            beginning of a .debug_info section.  The D3 spec mentions
113831452303b095a76295b08096b2840276db808b81sewardj            that this might be in some other shared object and
113931452303b095a76295b08096b2840276db808b81sewardj            executable.  But I don't see how the name of the other
114031452303b095a76295b08096b2840276db808b81sewardj            object/exe is specified.
114131452303b095a76295b08096b2840276db808b81sewardj
114231452303b095a76295b08096b2840276db808b81sewardj            At least for the DW_FORM_ref_addrs created by icc11, the
114331452303b095a76295b08096b2840276db808b81sewardj            references seem to be within the same object/executable.
114431452303b095a76295b08096b2840276db808b81sewardj            So for the moment we merely range-check, to see that they
114531452303b095a76295b08096b2840276db808b81sewardj            actually do specify a plausible offset within this
114631452303b095a76295b08096b2840276db808b81sewardj            object's .debug_info, and return the value unchanged.
1147ee93cdbee1e6a0db21be1ec4533a4022c9566388sewardj
1148ee93cdbee1e6a0db21be1ec4533a4022c9566388sewardj            In DWARF 2, DW_FORM_ref_addr is address-sized, but in
1149ee93cdbee1e6a0db21be1ec4533a4022c9566388sewardj            DWARF 3 and later, it is offset-sized.
115031452303b095a76295b08096b2840276db808b81sewardj         */
1151ee93cdbee1e6a0db21be1ec4533a4022c9566388sewardj         if (cc->version == 2) {
11525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            cts->u.val = (ULong)(UWord)get_UWord(c);
11535d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            cts->szB   = sizeof(UWord);
1154ee93cdbee1e6a0db21be1ec4533a4022c9566388sewardj         } else {
11555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            cts->u.val = get_Dwarfish_UWord(c, cc->is_dw64);
11565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            cts->szB   = cc->is_dw64 ? sizeof(ULong) : sizeof(UInt);
1157ee93cdbee1e6a0db21be1ec4533a4022c9566388sewardj         }
11585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("0x%lx", (UWord)cts->u.val);
11595d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (0) VG_(printf)("DW_FORM_ref_addr 0x%lx\n", (UWord)cts->u.val);
11605d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (/* the following is surely impossible, but ... */
11615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             !ML_(sli_is_valid)(cc->escn_debug_info)
11625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             || cts->u.val >= (ULong)cc->escn_debug_info.szB) {
116331452303b095a76295b08096b2840276db808b81sewardj            /* Hmm.  Offset is nonsensical for this object's .debug_info
116431452303b095a76295b08096b2840276db808b81sewardj               section.  Be safe and reject it. */
116531452303b095a76295b08096b2840276db808b81sewardj            cc->barf("get_Form_contents: DW_FORM_ref_addr points "
116631452303b095a76295b08096b2840276db808b81sewardj                     "outside .debug_info");
116731452303b095a76295b08096b2840276db808b81sewardj         }
116831452303b095a76295b08096b2840276db808b81sewardj         break;
116931452303b095a76295b08096b2840276db808b81sewardj
1170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_strp: {
1171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* this is an offset into .debug_str */
1172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UWord uw = (UWord)get_Dwarfish_UWord( c, cc->is_dw64 );
11735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (!ML_(sli_is_valid)(cc->escn_debug_str)
11745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             || uw >= cc->escn_debug_str.szB)
117531452303b095a76295b08096b2840276db808b81sewardj            cc->barf("get_Form_contents: DW_FORM_strp "
1176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     "points outside .debug_str");
1177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* FIXME: check the entire string lies inside debug_str,
1178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            not just the first byte of it. */
11795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor str
11805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            = ML_(cur_plus)( ML_(cur_from_sli)(cc->escn_debug_str), uw );
11815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (td3) {
11825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            HChar* tmp = ML_(cur_read_strdup)(str, "di.getFC.1");
11835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            TRACE_D3("(indirect string, offset: 0x%lx): %s", uw, tmp);
11845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ML_(dinfo_free)(tmp);
11855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
11865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = str;
11875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)(1 + (ULong)ML_(cur_strlen)(str));
1188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_string: {
11915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor str = get_AsciiZ(c);
11925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (td3) {
11935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            HChar* tmp = ML_(cur_read_strdup)(str, "di.getFC.2");
11945d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            TRACE_D3("%s", tmp);
11955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ML_(dinfo_free)(tmp);
11965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
11975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = str;
1198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* strlen is safe because get_AsciiZ already 'vetted' the
1199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            entire string */
12005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)(1 + (ULong)ML_(cur_strlen)(str));
1201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1203fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_ref1: {
12045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UChar u8   = get_UChar(c);
12055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UWord res  = cc->cu_start_offset + (UWord)u8;
12065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)res;
12075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
1208fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("<%lx>", res);
1209fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1210fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1211fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_ref2: {
12125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UShort u16 = get_UShort(c);
12135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UWord  res = cc->cu_start_offset + (UWord)u16;
12145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)res;
12155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
1216fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("<%lx>", res);
1217fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1218fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_ref4: {
12205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UInt  u32  = get_UInt(c);
12215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UWord res  = cc->cu_start_offset + (UWord)u32;
12225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)res;
12235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
1224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("<%lx>", res);
1225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1227fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_ref8: {
12285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong u64  = get_ULong(c);
12295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UWord res  = cc->cu_start_offset + (UWord)u64;
12305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)res;
12315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
1232fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("<%lx>", res);
1233fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1234fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1235fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_ref_udata: {
12365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong u64  = get_ULEB128(c);
12375d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UWord res  = cc->cu_start_offset + (UWord)u64;
12385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)res;
12395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
1240fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("<%lx>", res);
1241fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1242fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_flag: {
1244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UChar u8 = get_UChar(c);
1245b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("%u", (UInt)u8);
12465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)u8;
12475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 1;
1248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1250fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_flag_present:
1251fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("1");
12525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = 1;
12535d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 1;
1254fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_block1: {
12565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64b;
12575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64   = (ULong)get_UChar(c);
12585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor block = get_DiCursor_from_Cursor(c);
1259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("%llu byte block: ", u64);
1260b2250d38b573099db3bde67e8f1bbeb789542076sewardj         for (u64b = u64; u64b > 0; u64b--) {
1261b2250d38b573099db3bde67e8f1bbeb789542076sewardj            UChar u8 = get_UChar(c);
1262b2250d38b573099db3bde67e8f1bbeb789542076sewardj            TRACE_D3("%x ", (UInt)u8);
1263b2250d38b573099db3bde67e8f1bbeb789542076sewardj         }
12645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = block;
12655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)u64;
1266b2250d38b573099db3bde67e8f1bbeb789542076sewardj         break;
1267b2250d38b573099db3bde67e8f1bbeb789542076sewardj      }
1268b2250d38b573099db3bde67e8f1bbeb789542076sewardj      case DW_FORM_block2: {
12695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64b;
12705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64   = (ULong)get_UShort(c);
12715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor block = get_DiCursor_from_Cursor(c);
1272b2250d38b573099db3bde67e8f1bbeb789542076sewardj         TRACE_D3("%llu byte block: ", u64);
1273b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (u64b = u64; u64b > 0; u64b--) {
1274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            UChar u8 = get_UChar(c);
1275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            TRACE_D3("%x ", (UInt)u8);
1276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
12775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = block;
12785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)u64;
1279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1281fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_block4: {
12825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64b;
12835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64   = (ULong)get_UInt(c);
12845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor block = get_DiCursor_from_Cursor(c);
1285fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("%llu byte block: ", u64);
1286fba428cd266b8a39db641c5fd9523daa8939bed0tom         for (u64b = u64; u64b > 0; u64b--) {
1287fba428cd266b8a39db641c5fd9523daa8939bed0tom            UChar u8 = get_UChar(c);
1288fba428cd266b8a39db641c5fd9523daa8939bed0tom            TRACE_D3("%x ", (UInt)u8);
1289fba428cd266b8a39db641c5fd9523daa8939bed0tom         }
12905d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = block;
12915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)u64;
1292fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1293fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1294fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_exprloc:
1295fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_block: {
12965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64b;
12975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64   = (ULong)get_ULEB128(c);
12985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor block = get_DiCursor_from_Cursor(c);
1299fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("%llu byte block: ", u64);
1300fba428cd266b8a39db641c5fd9523daa8939bed0tom         for (u64b = u64; u64b > 0; u64b--) {
1301fba428cd266b8a39db641c5fd9523daa8939bed0tom            UChar u8 = get_UChar(c);
1302fba428cd266b8a39db641c5fd9523daa8939bed0tom            TRACE_D3("%x ", (UInt)u8);
1303fba428cd266b8a39db641c5fd9523daa8939bed0tom         }
13045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = block;
13055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)u64;
1306fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1307fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1308fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_ref_sig8: {
1309fba428cd266b8a39db641c5fd9523daa8939bed0tom         ULong  u64b;
1310d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         ULong  signature = get_ULong (c);
1311d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         ULong  work = signature;
1312fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("8 byte signature: ");
1313fba428cd266b8a39db641c5fd9523daa8939bed0tom         for (u64b = 8; u64b > 0; u64b--) {
1314d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            UChar u8 = work & 0xff;
1315fba428cd266b8a39db641c5fd9523daa8939bed0tom            TRACE_D3("%x ", (UInt)u8);
1316d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            work >>= 8;
1317fba428cd266b8a39db641c5fd9523daa8939bed0tom         }
1318d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* Due to the way that the hash table is constructed, the
1319d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            resulting DIE offset here is already "cooked".  See
1320d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            cook_die_using_form.  */
13215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = lookup_signatured_type (cc->signature_types, signature,
13225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                              c->barf);
13235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
1324fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1325fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1326fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_indirect:
13275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents (cts, cc, c, td3, (DW_FORM)get_ULEB128(c));
1328fba428cd266b8a39db641c5fd9523daa8939bed0tom         return;
1329fba428cd266b8a39db641c5fd9523daa8939bed0tom
1330f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      case DW_FORM_GNU_ref_alt:
13315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = get_Dwarfish_UWord(c, cc->is_dw64);
13325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = cc->is_dw64 ? sizeof(ULong) : sizeof(UInt);
13335d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("0x%lx", (UWord)cts->u.val);
13345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (0) VG_(printf)("DW_FORM_GNU_ref_alt 0x%lx\n", (UWord)cts->u.val);
13355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (/* the following is surely impossible, but ... */
13365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             !ML_(sli_is_valid)(cc->escn_debug_info_alt)
13375d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             || cts->u.val >= (ULong)cc->escn_debug_info_alt.szB) {
1338f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            /* Hmm.  Offset is nonsensical for this object's .debug_info
1339f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj               section.  Be safe and reject it. */
1340f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            cc->barf("get_Form_contents: DW_FORM_ref_addr points "
1341f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                     "outside alternate .debug_info");
1342f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         }
1343f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         break;
1344f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj
1345f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      case DW_FORM_GNU_strp_alt: {
1346f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         /* this is an offset into alternate .debug_str */
13475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         SizeT uw = (UWord)get_Dwarfish_UWord( c, cc->is_dw64 );
13485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (!ML_(sli_is_valid)(cc->escn_debug_str_alt)
13495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             || uw >= cc->escn_debug_str_alt.szB)
1350f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            cc->barf("get_Form_contents: DW_FORM_GNU_strp_alt "
1351f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                     "points outside alternate .debug_str");
1352f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         /* FIXME: check the entire string lies inside debug_str,
1353f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            not just the first byte of it. */
13545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor str
13555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            = ML_(cur_plus)( ML_(cur_from_sli)(cc->escn_debug_str_alt), uw);
13565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (td3) {
13575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            HChar* tmp = ML_(cur_read_strdup)(str, "di.getFC.3");
13585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            TRACE_D3("(indirect alt string, offset: 0x%lx): %s", uw, tmp);
13595d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ML_(dinfo_free)(tmp);
13605d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
13615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = str;
13625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)(1 + (ULong)ML_(cur_strlen)(str));
1363f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         break;
1364f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      }
1365f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj
1366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      default:
136731452303b095a76295b08096b2840276db808b81sewardj         VG_(printf)(
13685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            "get_Form_contents: unhandled %d (%s) at <%llx>\n",
136931452303b095a76295b08096b2840276db808b81sewardj            form, ML_(pp_DW_FORM)(form), get_position_of_Cursor(c));
1370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         c->barf("get_Form_contents: unhandled DW_FORM");
1371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
1376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
1377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Parsing of variable-related DIEs                     ---*/
1378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
1379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
1380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
1382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct _TempVar {
13837293d2530f8c60c1060f9f003e214cc341d35266philippe      HChar*  name; /* in DebugInfo's .strpool */
1384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Represent ranges economically.  nRanges is the number of
1385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ranges.  Cases:
1386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         0: .rngOneMin .rngOneMax .manyRanges are all zero
1387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         1: .rngOneMin .rngOneMax hold the range; .rngMany is NULL
1388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         2: .rngOneMin .rngOneMax are zero; .rngMany holds the ranges.
1389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         This is merely an optimisation to avoid having to allocate
1390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         and free the XArray in the common (98%) of cases where there
1391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         is zero or one address ranges. */
1392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord   nRanges;
1393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr    rngOneMin;
1394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr    rngOneMax;
13959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      XArray* rngMany; /* of AddrRange.  NON-UNIQUE PTR in AR_DINFO. */
13969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* Do not free .rngMany, since many TempVars will have the same
13979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         value.  Instead the associated storage is to be freed by
13989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         deleting 'rangetree', which stores a single copy of each
13999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         range. */
1400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* --- */
1401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int     level;
14029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      UWord   typeR; /* a cuOff */
1403b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GExpr*  gexpr; /* for this variable */
1404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GExpr*  fbGX;  /* to find the frame base of the enclosing fn, if
1405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        any */
14061636d33c13958b9c0e7d3059cdd5005746418eb2florian      HChar*  fName; /* declaring file name, or NULL */
1407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int     fLine; /* declaring file line number, or zero */
1408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* offset in .debug_info, so that abstract instances can be
1409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         found to satisfy references from concrete instances. */
1410b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord   dioff;
1411b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord   absOri; /* so the absOri fields refer to dioff fields
1412b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                         in some other, related TempVar. */
1413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1414b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TempVar;
1415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
14167cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define N_D3_VAR_STACK 48
1417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
1419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct {
1420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Contains the range stack: a stack of address ranges, one
1421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         stack entry for each nested scope.
1422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Some scope entries are created by function definitions
1424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (DW_AT_subprogram), and for those, we also note the GExpr
1425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         derived from its DW_AT_frame_base attribute, if any.
1426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Consequently it should be possible to find, for any
1427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         variable's DIE, the GExpr for the the containing function's
1428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT_frame_base by scanning back through the stack to find
1429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         the nearest entry associated with a function.  This somewhat
1430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         elaborate scheme is provided so as to make it possible to
1431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         obtain the correct DW_AT_frame_base expression even in the
1432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         presence of nested functions (or to be more precise, in the
1433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         presence of nested DW_AT_subprogram DIEs).
1434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      */
1435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int     sp; /* [sp] is innermost active entry; sp==-1 for empty
1436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     stack */
1437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      XArray* ranges[N_D3_VAR_STACK]; /* XArray of AddrRange */
1438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int     level[N_D3_VAR_STACK];  /* D3 DIE levels */
1439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool    isFunc[N_D3_VAR_STACK]; /* from DW_AT_subprogram? */
1440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GExpr*  fbGX[N_D3_VAR_STACK];   /* if isFunc, contains the FB
1441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                         expr, else NULL */
1442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* The file name table.  Is a mapping from integer index to the
14437293d2530f8c60c1060f9f003e214cc341d35266philippe         (permanent) copy of the string in in DebugInfo's .strpool. */
1444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      XArray* /* of UChar* */ filenameTable;
1445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   D3VarParser;
1447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
14486bd9dc18c043927c1196caba20a327238a179c42florianstatic void varstack_show ( D3VarParser* parser, const HChar* str ) {
1449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Word i, j;
1450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(printf)("  varstack (%s) {\n", str);
1451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i <= parser->sp; i++) {
1452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      XArray* xa = parser->ranges[i];
1453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(xa);
1454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(printf)("    [%ld] (level %d)", i, parser->level[i]);
1455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (parser->isFunc[i]) {
1456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(printf)(" (fbGX=%p)", parser->fbGX[i]);
1457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else {
1458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vg_assert(parser->fbGX[i] == NULL);
1459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(printf)(": ");
1461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (VG_(sizeXA)( xa ) == 0) {
1462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(printf)("** empty PC range array **");
1463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else {
1464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (j = 0; j < VG_(sizeXA)( xa ); j++) {
1465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            AddrRange* range = (AddrRange*) VG_(indexXA)( xa, j );
1466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            vg_assert(range);
1467a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart            VG_(printf)("[%#lx,%#lx] ", range->aMin, range->aMax);
1468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(printf)("\n");
1471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(printf)("  }\n");
1473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1474b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Remove from the stack, all entries with .level > 'level' */
1476b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
1477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid varstack_preen ( D3VarParser* parser, Bool td3, Int level )
1478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool changed = False;
1480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp < N_D3_VAR_STACK);
1481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
1482b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(parser->sp >= -1);
1483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (parser->sp == -1) break;
1484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (parser->level[parser->sp] <= level) break;
1485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (0)
1486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("BBBBAAAA varstack_pop [newsp=%d]\n", parser->sp-1);
1487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(parser->ranges[parser->sp]);
1488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Who allocated this xa?  get_range_list() or
1489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         unitary_range_list(). */
1490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(deleteXA)( parser->ranges[parser->sp] );
1491b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parser->ranges[parser->sp] = NULL;
1492b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parser->level[parser->sp]  = 0;
1493b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parser->isFunc[parser->sp] = False;
1494b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parser->fbGX[parser->sp]   = NULL;
1495b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parser->sp--;
1496b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      changed = True;
1497b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1498b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (changed && td3)
1499b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      varstack_show( parser, "after preen" );
1500b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1501b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1502b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void varstack_push ( CUConst* cc,
1503b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                            D3VarParser* parser,
1504b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                            Bool td3,
1505b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                            XArray* ranges, Int level,
1506b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                            Bool    isFunc, GExpr* fbGX ) {
1507b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (0)
1508b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3("BBBBAAAA varstack_push[newsp=%d]: %d  %p\n",
1509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            parser->sp+1, level, ranges);
1510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* First we need to zap everything >= 'level', as we are about to
1512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      replace any previous entry at 'level', so .. */
1513b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   varstack_preen(parser, /*td3*/False, level-1);
1514b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1515b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp >= -1);
1516b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp < N_D3_VAR_STACK);
1517b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (parser->sp == N_D3_VAR_STACK-1)
1518b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("varstack_push: N_D3_VAR_STACK is too low; "
1519b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               "increase and recompile");
1520b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (parser->sp >= 0)
1521b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(parser->level[parser->sp] < level);
1522b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->sp++;
1523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->ranges[parser->sp] == NULL);
1524b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->level[parser->sp]  == 0);
1525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->isFunc[parser->sp] == False);
1526b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->fbGX[parser->sp]   == NULL);
1527b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(ranges != NULL);
1528b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (!isFunc) vg_assert(fbGX == NULL);
1529b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->ranges[parser->sp] = ranges;
1530b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->level[parser->sp]  = level;
1531b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->isFunc[parser->sp] = isFunc;
1532b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->fbGX[parser->sp]   = fbGX;
1533b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (td3)
1534b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      varstack_show( parser, "after push" );
1535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
15385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* cts is derived from a DW_AT_location and so refers either to a
15395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   location expression or to a location list.  Figure out which, and
15405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   in both cases bundle the expression or location list into a
15415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   so-called GExpr (guarded expression). */
1542b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
15435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic GExpr* get_GX ( CUConst* cc, Bool td3, const FormContents* cts )
1544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   GExpr* gexpr = NULL;
15465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (cts->szB < 0) {
15475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      /* represents a non-empty in-line location expression, and
15485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur points at the image bytes */
15495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      gexpr = make_singleton_GX( cts->u.cur, (ULong)(- cts->szB) );
1550b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   else
15525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (cts->szB > 0) {
15535d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      /* represents a location list.  cts->u.val is the offset of it
15545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         in .debug_loc. */
1555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (!cc->cu_svma_known)
1556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         cc->barf("get_GX: location list, but CU svma is unknown");
15575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      gexpr = make_general_GX( cc, td3, cts->u.val, cc->cu_svma );
1558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   else {
1560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(0); /* else caller is bogus */
1561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return gexpr;
1563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
1567a0a73939b0398b6608fd6dbde49820ce6530d12cphilippevoid read_filename_table( /*MOD*/XArray* /* of UChar* */ filenameTable,
15685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                          CUConst* cc, ULong debug_line_offset,
1569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                          Bool td3 )
1570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool   is_dw64;
1572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Cursor c;
1573b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Word   i;
1574b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UShort version;
1575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar  opcode_base;
15761636d33c13958b9c0e7d3059cdd5005746418eb2florian   HChar* str;
1577b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1578a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   vg_assert(filenameTable && cc && cc->barf);
15795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (!ML_(sli_is_valid)(cc->escn_debug_line)
15805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj       || cc->escn_debug_line.szB <= debug_line_offset) {
1581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("read_filename_table: .debug_line is missing?");
15825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   }
1583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
15845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   init_Cursor( &c, cc->escn_debug_line, debug_line_offset, cc->barf,
1585b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                "Overrun whilst reading .debug_line section(1)" );
1586b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
15874c245e595b9f6300d3120408ca873f7115d9cc7dnjn   /* unit_length = */
15884c245e595b9f6300d3120408ca873f7115d9cc7dnjn      get_Initial_Length( &is_dw64, &c,
1589b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           "read_filename_table: invalid initial-length field" );
1590b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   version = get_UShort( &c );
1591fba428cd266b8a39db641c5fd9523daa8939bed0tom   if (version != 2 && version != 3 && version != 4)
1592fba428cd266b8a39db641c5fd9523daa8939bed0tom     cc->barf("read_filename_table: Only DWARF version 2, 3 and 4 line info "
1593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              "is currently supported.");
15944c245e595b9f6300d3120408ca873f7115d9cc7dnjn   /*header_length              = (ULong)*/ get_Dwarfish_UWord( &c, is_dw64 );
15954c245e595b9f6300d3120408ca873f7115d9cc7dnjn   /*minimum_instruction_length = */ get_UChar( &c );
1596fba428cd266b8a39db641c5fd9523daa8939bed0tom   if (version >= 4)
1597fba428cd266b8a39db641c5fd9523daa8939bed0tom      /*maximum_operations_per_insn = */ get_UChar( &c );
15984c245e595b9f6300d3120408ca873f7115d9cc7dnjn   /*default_is_stmt            = */ get_UChar( &c );
15994c245e595b9f6300d3120408ca873f7115d9cc7dnjn   /*line_base                  = (Char)*/ get_UChar( &c );
16004c245e595b9f6300d3120408ca873f7115d9cc7dnjn   /*line_range                 = */ get_UChar( &c );
1601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   opcode_base                = get_UChar( &c );
1602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* skip over "standard_opcode_lengths" */
1603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 1; i < (Word)opcode_base; i++)
1604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     (void)get_UChar( &c );
1605b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1606b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* skip over the directory names table */
1607b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (peek_UChar(&c) != 0) {
1608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     (void)get_AsciiZ(&c);
1609b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1610b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   (void)get_UChar(&c); /* skip terminating zero */
1611b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1612b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Read and record the file names table */
1613a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   vg_assert( VG_(sizeXA)( filenameTable ) == 0 );
1614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Add a dummy index-zero entry.  DWARF3 numbers its files
1615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      from 1, for some reason. */
1616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   str = ML_(addStr)( cc->di, "<unknown_file>", -1 );
1617a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   VG_(addToXA)( filenameTable, &str );
1618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (peek_UChar(&c) != 0) {
16195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiCursor cur = get_AsciiZ(&c);
16205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      str = ML_(addStrFromCursor)( cc->di, cur );
1621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("  read_filename_table: %ld %s\n",
1622a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               VG_(sizeXA)(filenameTable), str);
1623a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(addToXA)( filenameTable, &str );
1624b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      (void)get_ULEB128( &c ); /* skip directory index # */
1625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      (void)get_ULEB128( &c ); /* skip last mod time */
1626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      (void)get_ULEB128( &c ); /* file size */
1627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* We're done!  The rest of it is not interesting. */
1629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1631a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/* setup_cu_svma to be called when a cu is found at level 0,
1632a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   to establish the cu_svma. */
1633a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic void setup_cu_svma(CUConst* cc, Bool have_lo, Addr ip_lo, Bool td3)
1634a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{
1635a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Addr cu_svma;
1636a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   /* We have potentially more than one type of parser parsing the
1637a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      dwarf information. At least currently, each parser establishes
1638a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      the cu_svma. So, in case cu_svma_known, we check that the same
1639a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      result is obtained by the 2nd parsing of the cu.
1640a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1641a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Alternatively, we could reset cu_svma_known after each parsing
1642a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      and then check that we only see a single DW_TAG_compile_unit DIE
1643a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      at level 0, DWARF3 only allows exactly one top level DIE per
1644a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      CU. */
1645a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1646a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (have_lo)
1647a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      cu_svma = ip_lo;
1648a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   else {
1649a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Now, it may be that this DIE doesn't tell us the CU's
1650a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         SVMA, by way of not having a DW_AT_low_pc.  That's OK --
1651a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         the CU doesn't *have* to have its SVMA specified.
1652a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1653a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         But as per last para D3 spec sec 3.1.1 ("Normal and
1654a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         Partial Compilation Unit Entries", "If the base address
1655a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         (viz, the SVMA) is undefined, then any DWARF entry of
1656a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         structure defined interms of the base address of that
1657a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         compilation unit is not valid.".  So that means, if whilst
1658a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         processing the children of this top level DIE (or their
1659a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         children, etc) we see a DW_AT_range, and cu_svma_known is
1660a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         False, then the DIE that contains it is (per the spec)
1661a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         invalid, and we can legitimately stop and complain. */
1662a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* .. whereas The Reality is, simply assume the SVMA is zero
1663a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if it isn't specified. */
1664a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      cu_svma = 0;
1665a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
1666a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1667a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (cc->cu_svma_known) {
1668a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      vg_assert (cu_svma == cc->cu_svma);
1669a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   } else {
1670a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      cc->cu_svma_known = True;
1671a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      cc->cu_svma = cu_svma;
1672a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (0)
1673a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         TRACE_D3("setup_cu_svma: acquire CU_SVMA of %p\n", (void*) cc->cu_svma);
1674a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
1675a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe}
1676a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1677a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe__attribute__((noreturn))
1678a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic void dump_bad_die_and_barf(
1679896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe   const HChar *whichparser,
1680a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   DW_TAG dtag,
1681a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UWord posn,
1682a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Int level,
1683a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Cursor* c_die,  UWord saved_die_c_offset,
1684a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   g_abbv *abbv,
1685a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   CUConst* cc)
1686a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{
1687a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   FormContents cts;
1688a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UInt nf_i;
1689a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Bool  debug_types_flag;
1690a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Bool  alt_flag;
1691a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1692a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   set_position_of_Cursor( c_die,  saved_die_c_offset );
1693a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   posn = uncook_die( cc, posn, &debug_types_flag, &alt_flag );
1694a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   VG_(printf)(" <%d><%lx>: %s", level, posn, ML_(pp_DW_TAG)( dtag ) );
1695a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (debug_types_flag) {
1696a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(printf)(" (in .debug_types)");
1697a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
1698a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   else if (alt_flag) {
1699a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(printf)(" (in alternate .debug_info)");
1700a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
1701a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   VG_(printf)("\n");
1702a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   nf_i = 0;
1703a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   while (True) {
1704a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
1705a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
1706a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      nf_i++;
1707a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (attr == 0 && form == 0) break;
1708a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(printf)("     %18s: ", ML_(pp_DW_AT)(attr));
1709a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Get the form contents, so as to print them */
1710a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      get_Form_contents( &cts, cc, c_die, True, form );
1711a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(printf)("\t\n");
1712a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
1713896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe   VG_(printf)("\n%s:\n", whichparser);
1714896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe   cc->barf("confused by the above DIE");
1715a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe}
1716a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
17175c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe__attribute__((noinline))
17185c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippestatic void bad_DIE_confusion(int linenr)
17195c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe{
1720896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe   VG_(printf)("\nparse DIE(readdwarf3.c:%d): confused by:\n", linenr);
17215c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe}
17225c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe#define goto_bad_DIE do {bad_DIE_confusion(__LINE__); goto bad_DIE;} while (0)
1723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
17259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic void parse_var_DIE (
17269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/WordFM* /* of (XArray* of AddrRange, void) */ rangestree,
17279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/XArray* /* of TempVar* */ tempvars,
17289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/XArray* /* of GExpr* */ gexprs,
17299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/D3VarParser* parser,
17309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   DW_TAG dtag,
17319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   UWord posn,
17329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Int level,
17339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Cursor* c_die,
1734746e97e7098def65d59c79d5d661f9a757a837cdphilippe   g_abbv *abbv,
17359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   CUConst* cc,
17369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Bool td3
17379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj)
1738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
17395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   FormContents cts;
1740746e97e7098def65d59c79d5d661f9a757a837cdphilippe   UInt nf_i;
1741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1742b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UWord saved_die_c_offset  = get_position_of_Cursor( c_die );
1743b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1744b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   varstack_preen( parser, td3, level-1 );
1745b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1746f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   if (dtag == DW_TAG_compile_unit
1747f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj       || dtag == DW_TAG_type_unit
1748f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj       || dtag == DW_TAG_partial_unit) {
1749b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_lo    = False;
1750b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_hi1   = False;
1751de065a05bd7e802669c9074b129268bd9a5c308csewardj      Bool hiIsRelative = False;
1752b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_range = False;
1753b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr ip_lo    = 0;
1754b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr ip_hi1   = 0;
1755b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr rangeoff = 0;
1756746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
1757b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
1758746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
1759746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
1760746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
1761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
17625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
17635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_low_pc && cts.szB > 0) {
17645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ip_lo   = cts.u.val;
1765b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_lo = True;
1766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
17675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_high_pc && cts.szB > 0) {
17685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ip_hi1   = cts.u.val;
1769b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_hi1 = True;
1770de065a05bd7e802669c9074b129268bd9a5c308csewardj            if (form != DW_FORM_addr)
1771de065a05bd7e802669c9074b129268bd9a5c308csewardj               hiIsRelative = True;
1772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
17735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_ranges && cts.szB > 0) {
17745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            rangeoff   = cts.u.val;
1775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_range = True;
1776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
17775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_stmt_list && cts.szB > 0) {
1778a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            read_filename_table( parser->filenameTable, cc, cts.u.val, td3 );
1779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1781de065a05bd7e802669c9074b129268bd9a5c308csewardj      if (have_lo && have_hi1 && hiIsRelative)
1782de065a05bd7e802669c9074b129268bd9a5c308csewardj         ip_hi1 += ip_lo;
1783a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1784b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Now, does this give us an opportunity to find this
1785b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         CU's svma? */
1786a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (level == 0)
1787a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         setup_cu_svma(cc, have_lo, ip_lo, td3);
1788a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1789b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
1790b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (have_lo && have_hi1 && (!have_range)) {
1791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (ip_lo < ip_hi1)
1792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            varstack_push( cc, parser, td3,
1793b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           unitary_range_list(ip_lo, ip_hi1 - 1),
1794b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           level,
1795b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           False/*isFunc*/, NULL/*fbGX*/ );
17968130f91dc99a9ad90e516f8b449970ddaeaee911philippe         else if (ip_lo == 0 && ip_hi1 == 0)
17978130f91dc99a9ad90e516f8b449970ddaeaee911philippe            /* CU has no code, presumably?
17988130f91dc99a9ad90e516f8b449970ddaeaee911philippe               Such situations have been encountered for code
17998130f91dc99a9ad90e516f8b449970ddaeaee911philippe               compiled with -ffunction-sections -fdata-sections
18008130f91dc99a9ad90e516f8b449970ddaeaee911philippe               and linked with --gc-sections. Completely
18018130f91dc99a9ad90e516f8b449970ddaeaee911philippe               eliminated CU gives such 0 lo/hi pc. Similarly
18028130f91dc99a9ad90e516f8b449970ddaeaee911philippe               to a CU which has no lo/hi/range pc, we push
18038130f91dc99a9ad90e516f8b449970ddaeaee911philippe               an empty range list. */
18048130f91dc99a9ad90e516f8b449970ddaeaee911philippe            varstack_push( cc, parser, td3,
18058130f91dc99a9ad90e516f8b449970ddaeaee911philippe                           empty_range_list(),
18068130f91dc99a9ad90e516f8b449970ddaeaee911philippe                           level,
18078130f91dc99a9ad90e516f8b449970ddaeaee911philippe                           False/*isFunc*/, NULL/*fbGX*/ );
1808b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
1809b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if ((!have_lo) && (!have_hi1) && have_range) {
1810b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         varstack_push( cc, parser, td3,
1811b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        get_range_list( cc, td3,
1812b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                        rangeoff, cc->cu_svma ),
1813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        level,
1814b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        False/*isFunc*/, NULL/*fbGX*/ );
1815b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
1816b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if ((!have_lo) && (!have_hi1) && (!have_range)) {
1817b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* CU has no code, presumably? */
1818b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         varstack_push( cc, parser, td3,
1819b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        empty_range_list(),
1820b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        level,
1821b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        False/*isFunc*/, NULL/*fbGX*/ );
1822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
1823f578a69a862391896fa2f03359c3744022ae9783sewardj      if (have_lo && (!have_hi1) && have_range && ip_lo == 0) {
1824f578a69a862391896fa2f03359c3744022ae9783sewardj         /* broken DIE created by gcc-4.3.X ?  Ignore the
1825f578a69a862391896fa2f03359c3744022ae9783sewardj            apparently-redundant DW_AT_low_pc and use the DW_AT_ranges
1826f578a69a862391896fa2f03359c3744022ae9783sewardj            instead. */
1827f578a69a862391896fa2f03359c3744022ae9783sewardj         varstack_push( cc, parser, td3,
1828f578a69a862391896fa2f03359c3744022ae9783sewardj                        get_range_list( cc, td3,
1829f578a69a862391896fa2f03359c3744022ae9783sewardj                                        rangeoff, cc->cu_svma ),
1830f578a69a862391896fa2f03359c3744022ae9783sewardj                        level,
1831f578a69a862391896fa2f03359c3744022ae9783sewardj                        False/*isFunc*/, NULL/*fbGX*/ );
1832f578a69a862391896fa2f03359c3744022ae9783sewardj      } else {
1833f578a69a862391896fa2f03359c3744022ae9783sewardj         if (0) VG_(printf)("I got hlo %d hhi1 %d hrange %d\n",
1834f578a69a862391896fa2f03359c3744022ae9783sewardj                            (Int)have_lo, (Int)have_hi1, (Int)have_range);
18355c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
1836f578a69a862391896fa2f03359c3744022ae9783sewardj      }
1837b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1838b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_lexical_block || dtag == DW_TAG_subprogram) {
1840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   have_lo    = False;
1841b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   have_hi1   = False;
1842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   have_range = False;
1843de065a05bd7e802669c9074b129268bd9a5c308csewardj      Bool   hiIsRelative = False;
1844b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr   ip_lo      = 0;
1845b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr   ip_hi1     = 0;
1846b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr   rangeoff   = 0;
1847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   isFunc     = dtag == DW_TAG_subprogram;
1848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GExpr* fbGX       = NULL;
1849746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
1850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
1851746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
1852746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
1853746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
1854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
18555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
18565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_low_pc && cts.szB > 0) {
18575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ip_lo   = cts.u.val;
1858b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_lo = True;
1859b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
18605d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_high_pc && cts.szB > 0) {
18615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ip_hi1   = cts.u.val;
1862b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_hi1 = True;
1863de065a05bd7e802669c9074b129268bd9a5c308csewardj            if (form != DW_FORM_addr)
1864de065a05bd7e802669c9074b129268bd9a5c308csewardj               hiIsRelative = True;
1865b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
18665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_ranges && cts.szB > 0) {
18675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            rangeoff   = cts.u.val;
1868b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_range = True;
1869b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1870b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (isFunc
1871b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             && attr == DW_AT_frame_base
18725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             && cts.szB != 0 /* either scalar or nonempty block */) {
18735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            fbGX = get_GX( cc, False/*td3*/, &cts );
1874b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            vg_assert(fbGX);
187559a2d18d0ddfa241850017252b0804d469187d79sewardj            VG_(addToXA)(gexprs, &fbGX);
1876b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1877b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1878de065a05bd7e802669c9074b129268bd9a5c308csewardj      if (have_lo && have_hi1 && hiIsRelative)
1879de065a05bd7e802669c9074b129268bd9a5c308csewardj         ip_hi1 += ip_lo;
1880b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
1881b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (dtag == DW_TAG_subprogram
1882b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          && (!have_lo) && (!have_hi1) && (!have_range)) {
1883b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* This is legit - ignore it. Sec 3.3.3: "A subroutine entry
1884b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            representing a subroutine declaration that is not also a
1885b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            definition does not have code address or range
1886b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            attributes." */
1887b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
1888b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (dtag == DW_TAG_lexical_block
1889b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          && (!have_lo) && (!have_hi1) && (!have_range)) {
1890b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* I believe this is legit, and means the lexical block
1891b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            contains no insns (whatever that might mean).  Ignore. */
1892b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
1893b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (have_lo && have_hi1 && (!have_range)) {
1894b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* This scope supplies just a single address range. */
1895b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (ip_lo < ip_hi1)
1896b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            varstack_push( cc, parser, td3,
1897b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           unitary_range_list(ip_lo, ip_hi1 - 1),
1898b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           level, isFunc, fbGX );
1899b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
1900b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if ((!have_lo) && (!have_hi1) && have_range) {
1901b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* This scope supplies multiple address ranges via the use of
1902b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            a range list. */
1903b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         varstack_push( cc, parser, td3,
1904b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        get_range_list( cc, td3,
1905b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                        rangeoff, cc->cu_svma ),
1906b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        level, isFunc, fbGX );
1907b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
1908b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (have_lo && (!have_hi1) && (!have_range)) {
1909b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* This scope is bogus.  The D3 spec sec 3.4 (Lexical Block
1910b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Entries) says fairly clearly that a scope must have either
1911b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            _range or (_low_pc and _high_pc). */
1912b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* The spec is a bit ambiguous though.  Perhaps a single byte
1913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            range is intended?  See sec 2.17 (Code Addresses And Ranges) */
1914b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* This case is here because icc9 produced this:
1915b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         <2><13bd>: DW_TAG_lexical_block
1916b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            DW_AT_decl_line   : 5229
1917b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            DW_AT_decl_column : 37
1918b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            DW_AT_decl_file   : 1
1919b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            DW_AT_low_pc      : 0x401b03
1920b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         */
1921b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* Ignore (seems safe than pushing a single byte range) */
1922b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
19235c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
1924b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1925b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1926b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_variable || dtag == DW_TAG_formal_parameter) {
19271636d33c13958b9c0e7d3059cdd5005746418eb2florian      HChar* name        = NULL;
19289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      UWord  typeR       = D3_INVALID_CUOFF;
192981d24c396c66dde7db2d9b567451f99081a2eab7philippe      Bool   global      = False;
1930b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GExpr* gexpr       = NULL;
1931b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int    n_attrs     = 0;
1932b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord  abs_ori     = (UWord)D3_INVALID_CUOFF;
1933b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int    lineNo      = 0;
19341636d33c13958b9c0e7d3059cdd5005746418eb2florian      HChar* fileName    = NULL;
1935746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
1936b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
1937746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
1938746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
1939746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
1940b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
19415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
1942b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         n_attrs++;
19435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
19445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            name = ML_(addStrFromCursor)( cc->di, cts.u.cur );
1945b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1946b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == DW_AT_location
19475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             && cts.szB != 0 /* either scalar or nonempty block */) {
19485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            gexpr = get_GX( cc, False/*td3*/, &cts );
1949b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            vg_assert(gexpr);
195059a2d18d0ddfa241850017252b0804d469187d79sewardj            VG_(addToXA)(gexprs, &gexpr);
1951b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
19525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_type && cts.szB > 0) {
19535d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeR = cook_die_using_form( cc, cts.u.val, form );
1954b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
19555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_external && cts.szB > 0 && cts.u.val > 0) {
195681d24c396c66dde7db2d9b567451f99081a2eab7philippe            global = True;
1957b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
19585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_abstract_origin && cts.szB > 0) {
19595d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            abs_ori = (UWord)cts.u.val;
1960b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
19615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_declaration && cts.szB > 0 && cts.u.val > 0) {
19624c245e595b9f6300d3120408ca873f7115d9cc7dnjn            /*declaration = True;*/
1963b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
19645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_decl_line && cts.szB > 0) {
19655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            lineNo = (Int)cts.u.val;
1966b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
19675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_decl_file && cts.szB > 0) {
19685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            Int ftabIx = (Int)cts.u.val;
1969b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (ftabIx >= 1
1970b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                && ftabIx < VG_(sizeXA)( parser->filenameTable )) {
19711636d33c13958b9c0e7d3059cdd5005746418eb2florian               fileName = *(HChar**)
1972b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                          VG_(indexXA)( parser->filenameTable, ftabIx );
1973b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               vg_assert(fileName);
1974b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
1975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (0) VG_(printf)("XXX filename = %s\n", fileName);
1976b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
197881d24c396c66dde7db2d9b567451f99081a2eab7philippe      if (!global && dtag == DW_TAG_variable && level == 1) {
197981d24c396c66dde7db2d9b567451f99081a2eab7philippe         /* Case of a static variable. It is better to declare
198081d24c396c66dde7db2d9b567451f99081a2eab7philippe            it global as the variable is not really related to
198181d24c396c66dde7db2d9b567451f99081a2eab7philippe            a PC range, as its address can be used by program
198281d24c396c66dde7db2d9b567451f99081a2eab7philippe            counters outside of the ranges where it is visible . */
198381d24c396c66dde7db2d9b567451f99081a2eab7philippe         global = True;
198481d24c396c66dde7db2d9b567451f99081a2eab7philippe      }
198581d24c396c66dde7db2d9b567451f99081a2eab7philippe
1986b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* We'll collect it under if one of the following three
1987b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         conditions holds:
1988b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (1) has location and type    -> completed
1989b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (2) has type only            -> is an abstract instance
1990b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (3) has location and abs_ori -> is a concrete instance
19919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         Name, filename and line number are all optional frills.
1992b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      */
1993b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if ( /* 1 */ (gexpr && typeR != D3_INVALID_CUOFF)
1994b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           /* 2 */ || (typeR != D3_INVALID_CUOFF)
1995b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           /* 3 */ || (gexpr && abs_ori != (UWord)D3_INVALID_CUOFF) ) {
1996b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1997b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* Add this variable to the list of interesting looking
1998b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            variables.  Crucially, note along with it the address
1999b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            range(s) associated with the variable, which for locals
2000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            will be the address ranges at the top of the varparser's
2001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            stack. */
2002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         GExpr*   fbGX = NULL;
2003b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Word     i, nRanges;
2004b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         XArray*  /* of AddrRange */ xa;
2005b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TempVar* tv;
2006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* Stack can't be empty; we put a dummy entry on it for the
2007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            entire address range before starting with the DIEs for
2008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            this CU. */
2009b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vg_assert(parser->sp >= 0);
2010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
201181d24c396c66dde7db2d9b567451f99081a2eab7philippe         /* If this is a local variable (non-global), try to find
2012b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            the GExpr for the DW_AT_frame_base of the containing
2013b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            function.  It should have been pushed on the stack at the
2014b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            time we encountered its DW_TAG_subprogram DIE, so the way
2015b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            to find it is to scan back down the stack looking for it.
2016b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            If there isn't an enclosing stack entry marked 'isFunc'
2017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            then we must be seeing variable or formal param DIEs
2018b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            outside of a function, so we deem the Dwarf to be
2019b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            malformed if that happens.  Note that the fbGX may be NULL
2020b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if the containing DT_TAG_subprogram didn't supply a
2021b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            DW_AT_frame_base -- that's OK, but there must actually be
2022b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            a containing DW_TAG_subprogram. */
202381d24c396c66dde7db2d9b567451f99081a2eab7philippe         if (!global) {
2024b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Bool found = False;
2025b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            for (i = parser->sp; i >= 0; i--) {
2026b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (parser->isFunc[i]) {
2027b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  fbGX = parser->fbGX[i];
2028b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  found = True;
2029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  break;
2030b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               }
2031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
2032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (!found) {
2033b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (0 && VG_(clo_verbosity) >= 0) {
2034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  VG_(message)(Vg_DebugMsg,
203581d24c396c66dde7db2d9b567451f99081a2eab7philippe                     "warning: parse_var_DIE: non-global variable "
2036738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                     "outside DW_TAG_subprogram\n");
2037b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               }
20385c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe               /* goto_bad_DIE; */
2039b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               /* This seems to happen a lot.  Just ignore it -- if,
2040b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  when we come to evaluation of the location (guarded)
2041b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  expression, it requires a frame base value, and
2042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  there's no expression for that, then evaluation as a
2043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  whole will fail.  Harmless - a bit of a waste of
2044b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  cycles but nothing more. */
2045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
2046b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
204881d24c396c66dde7db2d9b567451f99081a2eab7philippe         /* re "global ? 0 : parser->sp" (twice), if the var is
204981d24c396c66dde7db2d9b567451f99081a2eab7philippe            marked 'global' then we must put it at the global scope,
2050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            as only the global scope (level 0) covers the entire PC
2051b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            address space.  It is asserted elsewhere that level 0
2052b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            always covers the entire address space. */
205381d24c396c66dde7db2d9b567451f99081a2eab7philippe         xa = parser->ranges[global ? 0 : parser->sp];
2054b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         nRanges = VG_(sizeXA)(xa);
2055b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vg_assert(nRanges >= 0);
2056b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
20579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         tv = ML_(dinfo_zalloc)( "di.readdwarf3.pvD.1", sizeof(TempVar) );
2058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->name   = name;
205981d24c396c66dde7db2d9b567451f99081a2eab7philippe         tv->level  = global ? 0 : parser->sp;
2060b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->typeR  = typeR;
2061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->gexpr  = gexpr;
2062b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->fbGX   = fbGX;
2063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->fName  = fileName;
2064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->fLine  = lineNo;
2065b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->dioff  = posn;
2066b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->absOri = abs_ori;
2067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* See explanation on definition of type TempVar for the
2069b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            reason for this elaboration. */
2070b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->nRanges = nRanges;
2071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->rngOneMin = 0;
2072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->rngOneMax = 0;
2073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->rngMany = NULL;
2074b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (nRanges == 1) {
2075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            AddrRange* range = VG_(indexXA)(xa, 0);
2076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            tv->rngOneMin = range->aMin;
2077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            tv->rngOneMax = range->aMax;
2078b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2079b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         else if (nRanges > 1) {
20809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            /* See if we already have a range list which is
20819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               structurally identical.  If so, use that; if not, clone
20829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               this one, and add it to our collection. */
20839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            UWord keyW, valW;
20849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            if (VG_(lookupFM)( rangestree, &keyW, &valW, (UWord)xa )) {
20859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               XArray* old = (XArray*)keyW;
20869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               tl_assert(valW == 0);
20879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               tl_assert(old != xa);
20889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               tv->rngMany = old;
20899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            } else {
20909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               XArray* cloned = VG_(cloneXA)( "di.readdwarf3.pvD.2", xa );
20919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               tv->rngMany = cloned;
20929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               VG_(addToFM)( rangestree, (UWord)cloned, 0 );
20939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            }
2094b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2095b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
209659a2d18d0ddfa241850017252b0804d469187d79sewardj         VG_(addToXA)( tempvars, &tv );
2097b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2098b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("  Recording this variable, with %ld PC range(s)\n",
2099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  VG_(sizeXA)(xa) );
2100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* collect stats on how effective the ->ranges special
2101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            casing is */
2102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (0) {
21039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            static Int ntot=0, ngt=0;
21049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            ntot++;
21059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            if (tv->rngMany) ngt++;
21069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            if (0 == (ntot % 100000))
21079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               VG_(printf)("XXXX %d tot, %d cloned\n", ntot, ngt);
2108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2109b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Here are some other weird cases seen in the wild:
2113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            We have a variable with a name and a type, but no
2115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            location.  I guess that's a sign that it has been
2116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            optimised away.  Ignore it.  Here's an example:
2117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            static Int lc_compar(void* n1, void* n2) {
2119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               MC_Chunk* mc1 = *(MC_Chunk**)n1;
2120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               MC_Chunk* mc2 = *(MC_Chunk**)n2;
2121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               return (mc1->data < mc2->data ? -1 : 1);
2122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
2123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Both mc1 and mc2 are like this
2125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            <2><5bc>: Abbrev Number: 21 (DW_TAG_variable)
2126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_name        : mc1
2127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_decl_file   : 1
2128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_decl_line   : 216
2129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_type        : <5d3>
2130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            whereas n1 and n2 do have locations specified.
2132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ---------------------------------------------
2134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            We see a DW_TAG_formal_parameter with a type, but
2136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            no name and no location.  It's probably part of a function type
2137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            construction, thusly, hence ignore it:
2138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         <1><2b4>: Abbrev Number: 12 (DW_TAG_subroutine_type)
2139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_sibling     : <2c9>
2140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_prototyped  : 1
2141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_type        : <114>
2142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         <2><2be>: Abbrev Number: 13 (DW_TAG_formal_parameter)
2143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_type        : <13e>
2144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         <2><2c3>: Abbrev Number: 13 (DW_TAG_formal_parameter)
2145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_type        : <133>
2146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ---------------------------------------------
2148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Is very minimal, like this:
2150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            <4><81d>: Abbrev Number: 44 (DW_TAG_variable)
2151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_abstract_origin: <7ba>
2152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            What that signifies I have no idea.  Ignore.
2153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ----------------------------------------------
2155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Is very minimal, like this:
2157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            <200f>: DW_TAG_formal_parameter
2158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_abstract_ori: <1f4c>
2159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_location    : 13440
2160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            What that signifies I have no idea.  Ignore.
2161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            It might be significant, though: the variable at least
2162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            has a location and so might exist somewhere.
2163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Maybe we should handle this.
2164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ---------------------------------------------
2166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2167b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            <22407>: DW_TAG_variable
2168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              DW_AT_name        : (indirect string, offset: 0x6579):
2169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                  vgPlain_trampoline_stuff_start
2170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              DW_AT_decl_file   : 29
2171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              DW_AT_decl_line   : 56
2172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              DW_AT_external    : 1
2173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              DW_AT_declaration : 1
2174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Nameless and typeless variable that has a location?  Who
2176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            knows.  Not me.
2177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            <2><3d178>: Abbrev Number: 22 (DW_TAG_variable)
2178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                 DW_AT_location    : 9 byte block: 3 c0 c7 13 38 0 0 0 0
2179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                     (DW_OP_addr: 3813c7c0)
2180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            No, really.  Check it out.  gcc is quite simply borked.
2182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            <3><168cc>: Abbrev Number: 141 (DW_TAG_variable)
2183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            // followed by no attributes, and the next DIE is a sibling,
2184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            // not a child
2185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            */
2186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return;
2188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  bad_DIE:
2190896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe   dump_bad_die_and_barf("parse_var_DIE", dtag, posn, level,
2191a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                         c_die, saved_die_c_offset,
2192a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                         abbv,
2193a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                         cc);
2194a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   /*NOTREACHED*/
2195a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe}
2196a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2197a0a73939b0398b6608fd6dbde49820ce6530d12cphilippetypedef
2198a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   struct {
2199a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* The file name table.  Is a mapping from integer index to the
2200a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         (permanent) copy of the string in DebugInfo's .strchunks. */
2201a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      XArray* /* of UChar* */ filenameTable;
2202f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   }
2203a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   D3InlParser;
2204a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2205a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/* Return the function name corresponding to absori.
2206a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   The return value is a (permanent) string in DebugInfo's .strchunks. */
2207a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic HChar* get_inlFnName (Int absori, CUConst* cc, Bool td3)
2208a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{
2209a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Cursor c;
2210a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   g_abbv *abbv;
2211a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   ULong  atag, abbv_code;
2212a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UInt   has_children;
2213a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UWord  posn;
2214a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   HChar *ret = NULL;
2215a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   FormContents cts;
2216a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UInt nf_i;
2217a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2218a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   init_Cursor (&c, cc->escn_debug_info, absori, cc->barf,
2219a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                "Overrun get_inlFnName absori");
2220a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2221a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   posn      = cook_die( cc, get_position_of_Cursor( &c ) );
2222a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   abbv_code = get_ULEB128( &c );
2223a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   abbv      = get_abbv ( cc, abbv_code);
2224a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   atag      = abbv->atag;
2225a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   TRACE_D3("\n");
2226a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   TRACE_D3(" <get_inlFnName><%lx>: Abbrev Number: %llu (%s)\n",
2227a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            posn, abbv_code, ML_(pp_DW_TAG)( atag ) );
2228a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2229a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (atag == 0)
2230a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      cc->barf("get_inlFnName: invalid zero tag on DIE");
2231a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2232a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   has_children = abbv->has_children;
2233a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (has_children != DW_children_no && has_children != DW_children_yes)
2234a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      cc->barf("get_inlFnName: invalid has_children value");
2235a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2236a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (atag != DW_TAG_subprogram)
2237a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      cc->barf("get_inlFnName: absori not a subprogram");
2238a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2239746e97e7098def65d59c79d5d661f9a757a837cdphilippe   nf_i = 0;
2240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
2241746e97e7098def65d59c79d5d661f9a757a837cdphilippe      DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
2242746e97e7098def65d59c79d5d661f9a757a837cdphilippe      DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
2243746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i++;
2244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (attr == 0 && form == 0) break;
2245a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      get_Form_contents( &cts, cc, &c, False/*td3*/, form );
2246a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (attr == DW_AT_name) {
2247a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         HChar *fnname;
2248a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (cts.szB >= 0)
2249a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            cc->barf("get_inlFnName: expecting indirect string");
2250a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         fnname = ML_(cur_read_strdup)( cts.u.cur,
2251a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                                        "get_inlFnName.1" );
2252a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ret = ML_(addStr)(cc->di, fnname, -1);
2253a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ML_(dinfo_free) (fnname);
2254a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         break;
2255a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
2256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2257a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2258a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (ret)
2259a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      return ret;
2260a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   else
2261a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      return ML_(addStr)(cc->di, "AbsOriFnNameNotFound", -1);
2262a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe}
2263a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2264a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/* Returns True if the (possibly) childrens of the current DIE are interesting
2265a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   to parse. Returns False otherwise.
2266a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   If the current DIE has a sibling, the non interesting children can
2267a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   maybe be skipped (if the DIE has a DW_AT_sibling).  */
2268a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe__attribute__((noinline))
2269a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic Bool parse_inl_DIE (
2270a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   /*MOD*/D3InlParser* parser,
2271a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   DW_TAG dtag,
2272a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UWord posn,
2273a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Int level,
2274a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Cursor* c_die,
2275a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   g_abbv *abbv,
2276a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   CUConst* cc,
2277a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Bool td3
2278a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe)
2279a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{
2280a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   FormContents cts;
2281a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UInt nf_i;
2282a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2283a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UWord saved_die_c_offset  = get_position_of_Cursor( c_die );
2284a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2285a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   /* Get info about DW_TAG_compile_unit and DW_TAG_partial_unit 'which
2286a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      in theory could also contain inlined fn calls).  */
2287a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (dtag == DW_TAG_compile_unit || dtag == DW_TAG_partial_unit) {
2288a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Bool have_lo    = False;
2289a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Addr ip_lo    = 0;
2290a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2291a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      nf_i = 0;
2292a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      while (True) {
2293a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
2294a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
2295a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         nf_i++;
2296a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == 0 && form == 0) break;
2297a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
2298a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == DW_AT_low_pc && cts.szB > 0) {
2299a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            ip_lo   = cts.u.val;
2300a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            have_lo = True;
2301a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2302a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == DW_AT_stmt_list && cts.szB > 0) {
2303a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            read_filename_table( parser->filenameTable, cc, cts.u.val, td3 );
2304a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2305a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
2306a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (level == 0)
2307a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         setup_cu_svma (cc, have_lo, ip_lo, td3);
2308a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
2309a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2310a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (dtag == DW_TAG_inlined_subroutine) {
2311a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Bool   have_lo    = False;
2312a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Bool   have_hi1   = False;
2313a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Bool   have_range = False;
2314a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Bool   hiIsRelative = False;
2315a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Addr   ip_lo      = 0;
2316a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Addr   ip_hi1     = 0;
2317a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Addr   rangeoff   = 0;
2318a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      HChar* caller_filename = NULL;
2319a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Int caller_lineno = 0;
2320a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Int inlinedfn_abstract_origin = 0;
2321a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2322a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      nf_i = 0;
2323a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      while (True) {
2324a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
2325a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
2326a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         nf_i++;
2327a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == 0 && form == 0) break;
2328a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
2329a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == DW_AT_call_file && cts.szB > 0) {
2330a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            Int ftabIx = (Int)cts.u.val;
2331a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (ftabIx >= 1
2332a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                && ftabIx < VG_(sizeXA)( parser->filenameTable )) {
2333a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               caller_filename = *(HChar**)
2334a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                          VG_(indexXA)( parser->filenameTable, ftabIx );
2335a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               vg_assert(caller_filename);
2336a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            }
2337a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (0) VG_(printf)("XXX caller_filename = %s\n", caller_filename);
2338a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2339a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == DW_AT_call_line && cts.szB > 0) {
2340a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            caller_lineno = cts.u.val;
2341a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2342a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2343a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == DW_AT_abstract_origin  && cts.szB > 0) {
2344a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            inlinedfn_abstract_origin = cts.u.val;
2345a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2346a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2347a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == DW_AT_low_pc && cts.szB > 0) {
2348a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            ip_lo   = cts.u.val;
2349a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            have_lo = True;
2350a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2351a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == DW_AT_high_pc && cts.szB > 0) {
2352a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            ip_hi1   = cts.u.val;
2353a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            have_hi1 = True;
2354a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (form != DW_FORM_addr)
2355a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               hiIsRelative = True;
2356a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2357a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == DW_AT_ranges && cts.szB > 0) {
2358a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            rangeoff   = cts.u.val;
2359a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            have_range = True;
2360a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2361a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
2362a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (have_lo && have_hi1 && hiIsRelative)
2363a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ip_hi1 += ip_lo;
2364a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Do we have something that looks sane? */
2365a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (dtag == DW_TAG_inlined_subroutine
2366a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe          && (!have_lo) && (!have_hi1) && (!have_range)) {
2367a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* Seems strange. How can an inlined subroutine have
2368a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            no code ? */
2369a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         goto_bad_DIE;
2370a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      } else
2371a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (have_lo && have_hi1 && (!have_range)) {
2372a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* This inlined call is just a single address range. */
2373a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (ip_lo < ip_hi1) {
2374a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            ML_(addInlInfo) (cc->di,
2375a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             ip_lo, ip_hi1,
2376a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             get_inlFnName (inlinedfn_abstract_origin, cc, td3),
2377a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             caller_filename,
2378a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             NULL, // INLINED TBD dirname ?????
2379a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             caller_lineno, level);
2380a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2381a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      } else if (have_range) {
2382a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* This inlined call is several address ranges. */
2383a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         XArray *ranges;
2384a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         Word j;
2385a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         HChar *inlfnname = get_inlFnName (inlinedfn_abstract_origin, cc, td3);
2386a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2387a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ranges = get_range_list( cc, td3,
2388a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                                  rangeoff, cc->cu_svma );
2389a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         for (j = 0; j < VG_(sizeXA)( ranges ); j++) {
2390a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            AddrRange* range = (AddrRange*) VG_(indexXA)( ranges, j );
2391a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            ML_(addInlInfo) (cc->di,
2392a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             range->aMin, range->aMax+1,
2393a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             // aMax+1 as range has its last bound included
2394a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             // while ML_(addInlInfo) expects last bound not
2395a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             // included.
2396a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             inlfnname,
2397a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             caller_filename,
2398a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             NULL, // INLINED TBD dirname ?????
2399a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             caller_lineno, level);
2400a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2401a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         VG_(deleteXA)( ranges );
2402a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      } else
2403a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         goto_bad_DIE;
2404a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
2405a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2406a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   // Only recursively parse the (possible) children for the DIE which
2407a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   // might maybe contain a DW_TAG_inlined_subroutine:
2408a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   return dtag == DW_TAG_lexical_block || dtag == DW_TAG_subprogram
2409a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      || dtag == DW_TAG_inlined_subroutine
2410a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      || dtag == DW_TAG_compile_unit || dtag == DW_TAG_partial_unit;
2411a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2412a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe  bad_DIE:
2413896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe   dump_bad_die_and_barf("parse_inl_DIE", dtag, posn, level,
2414a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                         c_die, saved_die_c_offset,
2415a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                         abbv,
2416a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                         cc);
2417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
2418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
2422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
2423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Parsing of type-related DIEs                         ---*/
2424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
2425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
2426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define N_D3_TYPE_STACK 16
2428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
2430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct {
24312acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      /* What source language?  'A'=Ada83/95,
24322acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj                                'C'=C/C++,
24332acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj                                'F'=Fortran,
24342acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj                                '?'=other
2435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Established once per compilation unit. */
2436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar language;
2437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* A stack of types which are currently under construction */
2438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int   sp; /* [sp] is innermost active entry; sp==-1 for empty
2439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   stack */
24409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* Note that the TyEnts in qparentE are temporary copies of the
24419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ones accumulating in the main tyent array.  So it is not safe
24429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         to free up anything on them when popping them off the stack
24439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         (iow, it isn't safe to use TyEnt__make_EMPTY on them).  Just
24449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         memset them to zero when done. */
24459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TyEnt qparentE[N_D3_TYPE_STACK]; /* parent TyEnts */
2446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int   qlevel[N_D3_TYPE_STACK];
2447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   D3TypeParser;
2450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
24516bd9dc18c043927c1196caba20a327238a179c42florianstatic void typestack_show ( D3TypeParser* parser, const HChar* str ) {
2452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Word i;
2453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(printf)("  typestack (%s) {\n", str);
2454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i <= parser->sp; i++) {
2455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(printf)("    [%ld] (level %d): ", i, parser->qlevel[i]);
24569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      ML_(pp_TyEnt)( &parser->qparentE[i] );
2457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(printf)("\n");
2458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(printf)("  }\n");
2460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Remove from the stack, all entries with .level > 'level' */
2463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
2464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid typestack_preen ( D3TypeParser* parser, Bool td3, Int level )
2465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
2466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool changed = False;
2467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp < N_D3_TYPE_STACK);
2468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
2469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(parser->sp >= -1);
2470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (parser->sp == -1) break;
2471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (parser->qlevel[parser->sp] <= level) break;
2472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (0)
2473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("BBBBAAAA typestack_pop [newsp=%d]\n", parser->sp-1);
24749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
24759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&parser->qparentE[parser->sp], 0, sizeof(TyEnt));
24769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      parser->qparentE[parser->sp].cuOff = D3_INVALID_CUOFF;
24779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      parser->qparentE[parser->sp].tag = Te_EMPTY;
24789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      parser->qlevel[parser->sp] = 0;
2479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parser->sp--;
2480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      changed = True;
2481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2482b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (changed && td3)
2483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      typestack_show( parser, "after preen" );
2484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool typestack_is_empty ( D3TypeParser* parser ) {
2487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp >= -1 && parser->sp < N_D3_TYPE_STACK);
2488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return parser->sp == -1;
2489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2491b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void typestack_push ( CUConst* cc,
2492b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             D3TypeParser* parser,
2493b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             Bool td3,
24949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                             TyEnt* parentE, Int level ) {
2495b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (0)
24969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TRACE_D3("BBBBAAAA typestack_push[newsp=%d]: %d  %05lx\n",
24979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            parser->sp+1, level, parentE->cuOff);
2498b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2499b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* First we need to zap everything >= 'level', as we are about to
2500b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      replace any previous entry at 'level', so .. */
2501b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   typestack_preen(parser, /*td3*/False, level-1);
2502b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2503b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp >= -1);
2504b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp < N_D3_TYPE_STACK);
2505b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (parser->sp == N_D3_TYPE_STACK-1)
2506b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("typestack_push: N_D3_TYPE_STACK is too low; "
2507b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               "increase and recompile");
2508b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (parser->sp >= 0)
2509b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(parser->qlevel[parser->sp] < level);
2510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->sp++;
25119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(parser->qparentE[parser->sp].tag == Te_EMPTY);
2512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->qlevel[parser->sp]  == 0);
25139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(parentE);
25149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(ML_(TyEnt__is_type)(parentE));
25159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(parentE->cuOff != D3_INVALID_CUOFF);
25169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   parser->qparentE[parser->sp] = *parentE;
2517b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->qlevel[parser->sp]  = level;
2518b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (td3)
2519b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      typestack_show( parser, "after push" );
2520b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2521b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
25222acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj/* True if the subrange type being parsed gives the bounds of an array. */
25232acc87cac77cedb3884e9e3a5188bac6edda5aeesewardjstatic Bool subrange_type_denotes_array_bounds ( D3TypeParser* parser,
25242acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj                                                 DW_TAG dtag ) {
25252acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   vg_assert(dtag == DW_TAG_subrange_type);
25262acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   /* For most languages, a subrange_type dtag always gives the
25272acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      bounds of an array.
25282acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      For Ada, there are additional conditions as a subrange_type
25292acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      is also used for other purposes. */
25302acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   if (parser->language != 'A')
25312acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      /* not Ada, so it definitely denotes an array bound. */
25322acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      return True;
25332acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   else
25342acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      /* Extra constraints for Ada: it only denotes an array bound if .. */
25352acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      return (! typestack_is_empty(parser)
25362acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj              && parser->qparentE[parser->sp].tag == Te_TyArray);
25372acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj}
2538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Parse a type-related DIE.  'parser' holds the current parser state.
2540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   'admin' is where the completed types are dumped.  'dtag' is the tag
2541b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for this DIE.  'c_die' points to the start of the data fields (FORM
2542746e97e7098def65d59c79d5d661f9a757a837cdphilippe   stuff) for the DIE.  abbv is the parsed abbreviation which describe
2543746e97e7098def65d59c79d5d661f9a757a837cdphilippe   the DIE.
2544b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   We may find the DIE uninteresting, in which case we should ignore
2546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   it.
25479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
25489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   What happens: the DIE is examined.  If uninteresting, it is ignored.
25499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Otherwise, the DIE gives rise to two things:
25509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
25519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   (1) the offset of this DIE in the CU -- the cuOffset, a UWord
25529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   (2) a TyAdmin structure, which holds the type, or related stuff
25539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
25549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   (2) is added at the end of 'tyadmins', at some index, say 'i'.
25559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
25569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   A pair (cuOffset, i) is added to 'tydict'.
25579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
25589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Hence 'tyadmins' holds the actual type entities, and 'tydict' holds
25599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   a mapping from cuOffset to the index of the corresponding entry in
25609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   'tyadmin'.
25619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
25629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   When resolving a cuOffset to a TyAdmin, first look up the cuOffset
25639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   in the tydict (by binary search).  This gives an index into
25649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   tyadmins, and the required entity lives in tyadmins at that index.
2565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/
2566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
25679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents,
2568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             /*MOD*/D3TypeParser* parser,
2569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             DW_TAG dtag,
2570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             UWord posn,
2571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             Int level,
2572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             Cursor* c_die,
2573746e97e7098def65d59c79d5d661f9a757a837cdphilippe                             g_abbv *abbv,
2574b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             CUConst* cc,
2575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             Bool td3 )
2576b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
25775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   FormContents cts;
2578a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UInt nf_i;
25799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEnt typeE;
25809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEnt atomE;
25819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEnt fieldE;
25829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEnt boundE;
2583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2584b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UWord saved_die_c_offset  = get_position_of_Cursor( c_die );
2585b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
25869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(memset)( &typeE,  0xAA, sizeof(typeE) );
25879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(memset)( &atomE,  0xAA, sizeof(atomE) );
25889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(memset)( &fieldE, 0xAA, sizeof(fieldE) );
25899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(memset)( &boundE, 0xAA, sizeof(boundE) );
25909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
2591b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* If we've returned to a level at or above any previously noted
2592b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parent, un-note it, so we don't believe we're still collecting
2593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      its children. */
2594b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   typestack_preen( parser, td3, level-1 );
2595b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2596f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   if (dtag == DW_TAG_compile_unit
2597f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj       || dtag == DW_TAG_type_unit
2598f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj       || dtag == DW_TAG_partial_unit) {
2599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* See if we can find DW_AT_language, since it is important for
2600b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         establishing array bounds (see DW_TAG_subrange_type below in
2601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         this fn) */
2602746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
2603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2604746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
2605746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
2606746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
2607b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
26085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
2609b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr != DW_AT_language)
2610b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            continue;
26115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (cts.szB <= 0)
26125c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe           goto_bad_DIE;
26135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         switch (cts.u.val) {
2614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_C89: case DW_LANG_C:
2615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_C_plus_plus: case DW_LANG_ObjC:
2616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_ObjC_plus_plus: case DW_LANG_UPC:
2617fba428cd266b8a39db641c5fd9523daa8939bed0tom            case DW_LANG_Upc: case DW_LANG_C99:
2618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               parser->language = 'C'; break;
2619b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_Fortran77: case DW_LANG_Fortran90:
2620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_Fortran95:
2621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               parser->language = 'F'; break;
26222acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj            case DW_LANG_Ada83: case DW_LANG_Ada95:
26232acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj               parser->language = 'A'; break;
26242acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj            case DW_LANG_Cobol74:
2625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_Cobol85: case DW_LANG_Pascal83:
2626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_Modula2: case DW_LANG_Java:
26272acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj            case DW_LANG_PLI:
2628fba428cd266b8a39db641c5fd9523daa8939bed0tom            case DW_LANG_D: case DW_LANG_Python:
2629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_Mips_Assembler:
2630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               parser->language = '?'; break;
2631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            default:
26325c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe               goto_bad_DIE;
2633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_base_type) {
2638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* We can pick up a new base type any time. */
26399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
26409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = D3_INVALID_CUOFF;
26419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyBase;
2642746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
2643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2644746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
2645746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
2646746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
2647b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
26485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
26495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
26509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            typeE.Te.TyBase.name
26515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = ML_(cur_read_strdup)( cts.u.cur,
26525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       "di.readdwarf3.ptD.base_type.1" );
2653b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
26545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_byte_size && cts.szB > 0) {
26555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyBase.szB = cts.u.val;
2656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
26575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_encoding && cts.szB > 0) {
26585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            switch (cts.u.val) {
2659b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               case DW_ATE_unsigned: case DW_ATE_unsigned_char:
266050c5093772c2b23fd0897d3590dcfaec1c92ac83tom               case DW_ATE_UTF: /* since DWARF4, e.g. char16_t from C++ */
2661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               case DW_ATE_boolean:/* FIXME - is this correct? */
26625db15403e889d4db339b342bc2a824ef0bfaa654sewardj               case DW_ATE_unsigned_fixed:
26639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                  typeE.Te.TyBase.enc = 'U'; break;
2664b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               case DW_ATE_signed: case DW_ATE_signed_char:
26655db15403e889d4db339b342bc2a824ef0bfaa654sewardj               case DW_ATE_signed_fixed:
26669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                  typeE.Te.TyBase.enc = 'S'; break;
2667b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               case DW_ATE_float:
26689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                  typeE.Te.TyBase.enc = 'F'; break;
2669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               case DW_ATE_complex_float:
26709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                  typeE.Te.TyBase.enc = 'C'; break;
2671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               default:
26725c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe                  goto_bad_DIE;
2673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
2674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Invent a name if it doesn't have one.  gcc-4.3
2678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         -ftree-vectorize is observed to emit nameless base types. */
26799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (!typeE.Te.TyBase.name)
26809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         typeE.Te.TyBase.name
26819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = ML_(dinfo_strdup)( "di.readdwarf3.ptD.base_type.2",
26829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                 "<anon_base_type>" );
2683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
2685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (/* must have a name */
26869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj          typeE.Te.TyBase.name == NULL
2687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          /* and a plausible size.  Yes, really 32: "complex long
2688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             double" apparently has size=32 */
26899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj          || typeE.Te.TyBase.szB < 0 || typeE.Te.TyBase.szB > 32
2690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          /* and a plausible encoding */
26919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj          || (typeE.Te.TyBase.enc != 'U'
26929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj              && typeE.Te.TyBase.enc != 'S'
26939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj              && typeE.Te.TyBase.enc != 'F'
26949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj              && typeE.Te.TyBase.enc != 'C'))
26955c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
2696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Last minute hack: if we see this
2697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         <1><515>: DW_TAG_base_type
2698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_byte_size   : 0
2699b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_encoding    : 5
2700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_name        : void
2701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         convert it into a real Void type. */
27029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (typeE.Te.TyBase.szB == 0
27039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj          && 0 == VG_(strcmp)("void", typeE.Te.TyBase.name)) {
27049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ML_(TyEnt__make_EMPTY)(&typeE);
27059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         typeE.tag = Te_TyVoid;
27069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         typeE.Te.TyVoid.isFake = False; /* it's a real one! */
2707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
27089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
2709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      goto acquire_Type;
2710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
27120e947cfedebda6da2e84fb61af431db5cf1275fcbart   /*
27130e947cfedebda6da2e84fb61af431db5cf1275fcbart    * An example of DW_TAG_rvalue_reference_type:
27140e947cfedebda6da2e84fb61af431db5cf1275fcbart    *
27150e947cfedebda6da2e84fb61af431db5cf1275fcbart    * $ readelf --debug-dump /usr/lib/debug/usr/lib/libstdc++.so.6.0.16.debug
27160e947cfedebda6da2e84fb61af431db5cf1275fcbart    *  <1><1014>: Abbrev Number: 55 (DW_TAG_rvalue_reference_type)
27170e947cfedebda6da2e84fb61af431db5cf1275fcbart    *     <1015>   DW_AT_byte_size   : 4
27180e947cfedebda6da2e84fb61af431db5cf1275fcbart    *     <1016>   DW_AT_type        : <0xe52>
27190e947cfedebda6da2e84fb61af431db5cf1275fcbart    */
2720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_pointer_type || dtag == DW_TAG_reference_type
27210e947cfedebda6da2e84fb61af431db5cf1275fcbart       || dtag == DW_TAG_ptr_to_member_type
27220e947cfedebda6da2e84fb61af431db5cf1275fcbart       || dtag == DW_TAG_rvalue_reference_type) {
2723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* This seems legit for _pointer_type and _reference_type.  I
2724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         don't know if rolling _ptr_to_member_type in here really is
2725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         legit, but it's better than not handling it at all. */
27269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
27279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = D3_INVALID_CUOFF;
27280e947cfedebda6da2e84fb61af431db5cf1275fcbart      switch (dtag) {
27290e947cfedebda6da2e84fb61af431db5cf1275fcbart      case DW_TAG_pointer_type:
27300e947cfedebda6da2e84fb61af431db5cf1275fcbart         typeE.tag = Te_TyPtr;
27310e947cfedebda6da2e84fb61af431db5cf1275fcbart         break;
27320e947cfedebda6da2e84fb61af431db5cf1275fcbart      case DW_TAG_reference_type:
27330e947cfedebda6da2e84fb61af431db5cf1275fcbart         typeE.tag = Te_TyRef;
27340e947cfedebda6da2e84fb61af431db5cf1275fcbart         break;
27350e947cfedebda6da2e84fb61af431db5cf1275fcbart      case DW_TAG_ptr_to_member_type:
27360e947cfedebda6da2e84fb61af431db5cf1275fcbart         typeE.tag = Te_TyPtrMbr;
27370e947cfedebda6da2e84fb61af431db5cf1275fcbart         break;
27380e947cfedebda6da2e84fb61af431db5cf1275fcbart      case DW_TAG_rvalue_reference_type:
27390e947cfedebda6da2e84fb61af431db5cf1275fcbart         typeE.tag = Te_TyRvalRef;
27400e947cfedebda6da2e84fb61af431db5cf1275fcbart         break;
27410e947cfedebda6da2e84fb61af431db5cf1275fcbart      default:
27420e947cfedebda6da2e84fb61af431db5cf1275fcbart         vg_assert(False);
27430e947cfedebda6da2e84fb61af431db5cf1275fcbart      }
2744b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* target type defaults to void */
27459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyPorR.typeR = D3_FAKEVOID_CUOFF;
27460e947cfedebda6da2e84fb61af431db5cf1275fcbart      /* These four type kinds don't *have* to specify their size, in
274731452303b095a76295b08096b2840276db808b81sewardj         which case we assume it's a machine word.  But if they do
274831452303b095a76295b08096b2840276db808b81sewardj         specify it, it must be a machine word :-)  This probably
274931452303b095a76295b08096b2840276db808b81sewardj         assumes that the word size of the Dwarf3 we're reading is the
275031452303b095a76295b08096b2840276db808b81sewardj         same size as that on the machine.  gcc appears to give a size
275131452303b095a76295b08096b2840276db808b81sewardj         whereas icc9 doesn't. */
275231452303b095a76295b08096b2840276db808b81sewardj      typeE.Te.TyPorR.szB = sizeof(UWord);
2753746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
2754b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2755746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
2756746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
2757746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
2758b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
27595d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
27605d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_byte_size && cts.szB > 0) {
27615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyPorR.szB = cts.u.val;
2762b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
27635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_type && cts.szB > 0) {
27645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyPorR.typeR
27655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = cook_die_using_form( cc, (UWord)cts.u.val, form );
2766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2767b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
276931452303b095a76295b08096b2840276db808b81sewardj      if (typeE.Te.TyPorR.szB != sizeof(UWord))
27705c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
2771b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      else
2772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto acquire_Type;
2773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_enumeration_type) {
2776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Create a new Type to hold the results. */
27779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
27789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = posn;
27799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyEnum;
27809d82d0f293c83ff2b8c3ab07065d8454059452bemjw      Bool is_decl = False;
27819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyEnum.atomRs
27829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ptD.enum_type.1",
27839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                       ML_(dinfo_free),
27849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                       sizeof(UWord) );
2785746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i=0;
2786b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2787746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
2788746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
2789746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
2790b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
27915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
27925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
27939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            typeE.Te.TyEnum.name
27945d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = ML_(cur_read_strdup)( cts.u.cur,
27955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       "di.readdwarf3.pTD.enum_type.2" );
2796b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
27975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_byte_size && cts.szB > 0) {
27985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyEnum.szB = cts.u.val;
2799b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
28009d82d0f293c83ff2b8c3ab07065d8454059452bemjw         if (attr == DW_AT_declaration) {
28019d82d0f293c83ff2b8c3ab07065d8454059452bemjw            is_decl = True;
28029d82d0f293c83ff2b8c3ab07065d8454059452bemjw         }
2803b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
28046ece231961274337eb8303aba3ac5247fc7d1ef9sewardj
28056ece231961274337eb8303aba3ac5247fc7d1ef9sewardj      if (!typeE.Te.TyEnum.name)
28066ece231961274337eb8303aba3ac5247fc7d1ef9sewardj         typeE.Te.TyEnum.name
28076ece231961274337eb8303aba3ac5247fc7d1ef9sewardj            = ML_(dinfo_strdup)( "di.readdwarf3.pTD.enum_type.3",
28086ece231961274337eb8303aba3ac5247fc7d1ef9sewardj                                 "<anon_enum_type>" );
28096ece231961274337eb8303aba3ac5247fc7d1ef9sewardj
2810b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
28112acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      if (typeE.Te.TyEnum.szB == 0
28122acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj          /* we must know the size */
28132acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj          /* but not for Ada, which uses such dummy
28149d82d0f293c83ff2b8c3ab07065d8454059452bemjw             enumerations as helper for gdb ada mode.
28159d82d0f293c83ff2b8c3ab07065d8454059452bemjw             Also GCC allows incomplete enums as GNU extension.
28169d82d0f293c83ff2b8c3ab07065d8454059452bemjw             http://gcc.gnu.org/onlinedocs/gcc/Incomplete-Enums.html
28179d82d0f293c83ff2b8c3ab07065d8454059452bemjw             These are marked as DW_AT_declaration and won't have
28189d82d0f293c83ff2b8c3ab07065d8454059452bemjw             a size. They can only be used in declaration or as
28199d82d0f293c83ff2b8c3ab07065d8454059452bemjw             pointer types.  You can't allocate variables or storage
28209d82d0f293c83ff2b8c3ab07065d8454059452bemjw             using such an enum type. (Also GCC seems to have a bug
28219d82d0f293c83ff2b8c3ab07065d8454059452bemjw             that will put such an enumeration_type into a .debug_types
28229d82d0f293c83ff2b8c3ab07065d8454059452bemjw             unit which should only contain complete types.) */
28239d82d0f293c83ff2b8c3ab07065d8454059452bemjw          && (parser->language != 'A' && !is_decl)) {
28245c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
2825d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      }
2826d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
2827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* On't stack! */
28289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typestack_push( cc, parser, td3, &typeE, level );
2829b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      goto acquire_Type;
2830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2832f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj   /* gcc (GCC) 4.4.0 20081017 (experimental) occasionally produces
2833f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      DW_TAG_enumerator with only a DW_AT_name but no
2834f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      DW_AT_const_value.  This is in violation of the Dwarf3 standard,
2835f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      and appears to be a new "feature" of gcc - versions 4.3.x and
2836f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      earlier do not appear to do this.  So accept DW_TAG_enumerator
2837f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      which only have a name but no value.  An example:
2838f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj
2839f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      <1><180>: Abbrev Number: 6 (DW_TAG_enumeration_type)
2840f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <181>   DW_AT_name        : (indirect string, offset: 0xda70):
2841f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj                                     QtMsgType
2842f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <185>   DW_AT_byte_size   : 4
2843f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <186>   DW_AT_decl_file   : 14
2844f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <187>   DW_AT_decl_line   : 1480
2845f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <189>   DW_AT_sibling     : <0x1a7>
2846f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      <2><18d>: Abbrev Number: 7 (DW_TAG_enumerator)
2847f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <18e>   DW_AT_name        : (indirect string, offset: 0x9e18):
2848f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj                                     QtDebugMsg
2849f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      <2><192>: Abbrev Number: 7 (DW_TAG_enumerator)
2850f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <193>   DW_AT_name        : (indirect string, offset: 0x1505f):
2851f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj                                     QtWarningMsg
2852f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      <2><197>: Abbrev Number: 7 (DW_TAG_enumerator)
2853f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <198>   DW_AT_name        : (indirect string, offset: 0x16f4a):
2854f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj                                     QtCriticalMsg
2855f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      <2><19c>: Abbrev Number: 7 (DW_TAG_enumerator)
2856f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <19d>   DW_AT_name        : (indirect string, offset: 0x156dd):
2857f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj                                     QtFatalMsg
2858f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      <2><1a1>: Abbrev Number: 7 (DW_TAG_enumerator)
2859f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <1a2>   DW_AT_name        : (indirect string, offset: 0x13660):
2860f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj                                     QtSystemMsg
2861f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj   */
2862b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_enumerator) {
28639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)( &atomE, 0, sizeof(atomE) );
28649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      atomE.cuOff = posn;
28659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      atomE.tag   = Te_Atom;
2866746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
2867b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2868746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
2869746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
2870746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
2871b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
28725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
28735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
28749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            atomE.Te.Atom.name
28755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj              = ML_(cur_read_strdup)( cts.u.cur,
28765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                      "di.readdwarf3.pTD.enumerator.1" );
2877b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
28785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_const_value && cts.szB > 0) {
28795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            atomE.Te.Atom.value      = cts.u.val;
2880f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj            atomE.Te.Atom.valueKnown = True;
2881b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2882b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2883b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
2884f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      if (atomE.Te.Atom.name == NULL)
28855c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
2886b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have a plausible parent? */
28875c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe      if (typestack_is_empty(parser)) goto_bad_DIE;
28889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
28899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(parser->qparentE[parser->sp].cuOff != D3_INVALID_CUOFF);
28905c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe      if (level != parser->qlevel[parser->sp]+1) goto_bad_DIE;
28915c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe      if (parser->qparentE[parser->sp].tag != Te_TyEnum) goto_bad_DIE;
2892b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Record this child in the parent */
28939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(parser->qparentE[parser->sp].Te.TyEnum.atomRs);
28949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(addToXA)( parser->qparentE[parser->sp].Te.TyEnum.atomRs,
28959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                    &atomE );
2896b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* And record the child itself */
2897b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      goto acquire_Atom;
2898b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2899b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
29006a3a28409187ca6813b228afaf2af288c1fcd73dsewardj   /* Treat DW_TAG_class_type as if it was a DW_TAG_structure_type.  I
29016a3a28409187ca6813b228afaf2af288c1fcd73dsewardj      don't know if this is correct, but it at least makes this reader
29026a3a28409187ca6813b228afaf2af288c1fcd73dsewardj      usable for gcc-4.3 produced Dwarf3. */
29036a3a28409187ca6813b228afaf2af288c1fcd73dsewardj   if (dtag == DW_TAG_structure_type || dtag == DW_TAG_class_type
29046a3a28409187ca6813b228afaf2af288c1fcd73dsewardj       || dtag == DW_TAG_union_type) {
2905b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_szB = False;
2906b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool is_decl  = False;
2907b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool is_spec  = False;
2908b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Create a new Type to hold the results. */
29099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
29109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = posn;
29119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyStOrUn;
29129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyStOrUn.name = NULL;
29130abc4193f82294904ed9478fa80394224c03fcc0dejanj      typeE.Te.TyStOrUn.typeR = D3_INVALID_CUOFF;
29149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyStOrUn.fieldRs
29159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.pTD.struct_type.1",
29169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                       ML_(dinfo_free),
29179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                       sizeof(UWord) );
29189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyStOrUn.complete = True;
29199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyStOrUn.isStruct = dtag == DW_TAG_structure_type
29209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                   || dtag == DW_TAG_class_type;
2921746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
2922b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2923746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
2924746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
2925746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
2926b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
29275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
29285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
29299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            typeE.Te.TyStOrUn.name
29305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = ML_(cur_read_strdup)( cts.u.cur,
29315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       "di.readdwarf3.ptD.struct_type.2" );
2932b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
29335d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_byte_size && cts.szB >= 0) {
29345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyStOrUn.szB = cts.u.val;
2935b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_szB = True;
2936b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
29375d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_declaration && cts.szB > 0 && cts.u.val > 0) {
2938b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            is_decl = True;
2939b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
29405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_specification && cts.szB > 0 && cts.u.val > 0) {
2941b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            is_spec = True;
2942b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
29430abc4193f82294904ed9478fa80394224c03fcc0dejanj         if (attr == DW_AT_signature && form == DW_FORM_ref_sig8
29440abc4193f82294904ed9478fa80394224c03fcc0dejanj             && cts.szB > 0) {
29450abc4193f82294904ed9478fa80394224c03fcc0dejanj            have_szB = True;
29460abc4193f82294904ed9478fa80394224c03fcc0dejanj            typeE.Te.TyStOrUn.szB = 8;
29470abc4193f82294904ed9478fa80394224c03fcc0dejanj            typeE.Te.TyStOrUn.typeR
29480abc4193f82294904ed9478fa80394224c03fcc0dejanj               = cook_die_using_form( cc, (UWord)cts.u.val, form );
29490abc4193f82294904ed9478fa80394224c03fcc0dejanj         }
2950b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2951b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
2952b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (is_decl && (!is_spec)) {
2953b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* It's a DW_AT_declaration.  We require the name but
2954b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            nothing else. */
295500888885d88a5264711c22074cfd3462020cbee6sewardj         /* JRS 2012-06-28: following discussion w/ tromey, if the the
295600888885d88a5264711c22074cfd3462020cbee6sewardj            type doesn't have name, just make one up, and accept it.
295700888885d88a5264711c22074cfd3462020cbee6sewardj            It might be referred to by other DIEs, so ignoring it
295800888885d88a5264711c22074cfd3462020cbee6sewardj            doesn't seem like a safe option. */
29599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (typeE.Te.TyStOrUn.name == NULL)
296000888885d88a5264711c22074cfd3462020cbee6sewardj            typeE.Te.TyStOrUn.name
296100888885d88a5264711c22074cfd3462020cbee6sewardj               = ML_(dinfo_strdup)( "di.readdwarf3.ptD.struct_type.3",
296200888885d88a5264711c22074cfd3462020cbee6sewardj                                    "<anon_struct_type>" );
29639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         typeE.Te.TyStOrUn.complete = False;
2964b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj         /* JRS 2009 Aug 10: <possible kludge>? */
2965b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj         /* Push this tyent on the stack, even though it's incomplete.
2966b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj            It appears that gcc-4.4 on Fedora 11 will sometimes create
2967b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj            DW_TAG_member entries for it, and so we need to have a
2968b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj            plausible parent present in order for that to work.  See
2969b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj            #200029 comments 8 and 9. */
2970b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj         typestack_push( cc, parser, td3, &typeE, level );
2971b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj         /* </possible kludge> */
2972b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto acquire_Type;
2973b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2974b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if ((!is_decl) /* && (!is_spec) */) {
2975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* this is the common, ordinary case */
29765c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         /* The name can be present, or not */
29775c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         if (!have_szB) {
29785c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe            /* We must know the size.
29795c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe               But in Ada, record with discriminants might have no size.
29805c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe               But in C, VLA in the middle of a struct (gcc extension)
29815c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe               might have no size.
29825c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe               Instead, some GNAT dwarf extensions and/or dwarf entries
29835c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe               allow to calculate the struct size at runtime.
29845c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe               We cannot do that (yet?) so, the temporary kludge is to use
29855c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe               a small size. */
29865c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe            typeE.Te.TyStOrUn.szB = 1;
29875c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         }
2988b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* On't stack! */
29899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         typestack_push( cc, parser, td3, &typeE, level );
2990b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto acquire_Type;
2991b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2992b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      else {
2993b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* don't know how to handle any other variants just now */
29945c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
2995b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2996b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2997b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2998b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_member) {
2999b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Acquire member entries for both DW_TAG_structure_type and
3000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_TAG_union_type.  They differ minorly, in that struct
3001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         members must have a DW_AT_data_member_location expression
3002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         whereas union members must not. */
3003b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool parent_is_struct;
30049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)( &fieldE, 0, sizeof(fieldE) );
30059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      fieldE.cuOff = posn;
30069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      fieldE.tag   = Te_Field;
30079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      fieldE.Te.Field.typeR = D3_INVALID_CUOFF;
3008746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
3009b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
3010746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
3011746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
3012746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
3013b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
30145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
30155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
30169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            fieldE.Te.Field.name
30175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = ML_(cur_read_strdup)( cts.u.cur,
30185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       "di.readdwarf3.ptD.member.1" );
3019b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
30205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_type && cts.szB > 0) {
30215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            fieldE.Te.Field.typeR
30225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = cook_die_using_form( cc, (UWord)cts.u.val, form );
3023b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
30243c9cf3442185b5891e15450d6e3058aeff6796fetom         /* There are 2 different cases for DW_AT_data_member_location.
30253c9cf3442185b5891e15450d6e3058aeff6796fetom            If it is a constant class attribute, it contains byte offset
30263c9cf3442185b5891e15450d6e3058aeff6796fetom            from the beginning of the containing entity.
30273c9cf3442185b5891e15450d6e3058aeff6796fetom            Otherwise it is a location expression.  */
30285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_data_member_location && cts.szB > 0) {
30293c9cf3442185b5891e15450d6e3058aeff6796fetom            fieldE.Te.Field.nLoc = -1;
30305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            fieldE.Te.Field.pos.offset = cts.u.val;
30315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
30325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_data_member_location && cts.szB <= 0) {
30335d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            fieldE.Te.Field.nLoc = (UWord)(-cts.szB);
30343c9cf3442185b5891e15450d6e3058aeff6796fetom            fieldE.Te.Field.pos.loc
30355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = ML_(cur_read_memdup)( cts.u.cur,
30365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       (SizeT)fieldE.Te.Field.nLoc,
30375d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       "di.readdwarf3.ptD.member.2" );
3038b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3039b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3040b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have a plausible parent? */
30415c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe      if (typestack_is_empty(parser)) goto_bad_DIE;
30429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
30439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(parser->qparentE[parser->sp].cuOff != D3_INVALID_CUOFF);
30445c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe      if (level != parser->qlevel[parser->sp]+1) goto_bad_DIE;
30455c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe      if (parser->qparentE[parser->sp].tag != Te_TyStOrUn) goto_bad_DIE;
3046b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane?  If this a member of a
3047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         struct, we must have a location expression; but if a member
3048b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         of a union that is irrelevant (D3 spec sec 5.6.6).  We ought
3049b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         to reject in the latter case, but some compilers have been
3050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         observed to emit constant-zero expressions.  So just ignore
3051b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         them. */
3052b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parent_is_struct
30539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         = parser->qparentE[parser->sp].Te.TyStOrUn.isStruct;
30549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (!fieldE.Te.Field.name)
30559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         fieldE.Te.Field.name
30569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = ML_(dinfo_strdup)( "di.readdwarf3.ptD.member.3",
30579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                 "<anon_field>" );
30589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(fieldE.Te.Field.name);
30599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (fieldE.Te.Field.typeR == D3_INVALID_CUOFF)
30605c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
30613c9cf3442185b5891e15450d6e3058aeff6796fetom      if (fieldE.Te.Field.nLoc) {
306207de5ddba10bfebab8416a8f79c349faa62bbaa1tom         if (!parent_is_struct) {
306307de5ddba10bfebab8416a8f79c349faa62bbaa1tom            /* If this is a union type, pretend we haven't seen the data
306407de5ddba10bfebab8416a8f79c349faa62bbaa1tom               member location expression, as it is by definition
306507de5ddba10bfebab8416a8f79c349faa62bbaa1tom               redundant (it must be zero). */
30663c9cf3442185b5891e15450d6e3058aeff6796fetom            if (fieldE.Te.Field.nLoc > 0)
30673c9cf3442185b5891e15450d6e3058aeff6796fetom               ML_(dinfo_free)(fieldE.Te.Field.pos.loc);
30683c9cf3442185b5891e15450d6e3058aeff6796fetom            fieldE.Te.Field.pos.loc = NULL;
306907de5ddba10bfebab8416a8f79c349faa62bbaa1tom            fieldE.Te.Field.nLoc = 0;
307007de5ddba10bfebab8416a8f79c349faa62bbaa1tom         }
307107de5ddba10bfebab8416a8f79c349faa62bbaa1tom         /* Record this child in the parent */
307207de5ddba10bfebab8416a8f79c349faa62bbaa1tom         fieldE.Te.Field.isStruct = parent_is_struct;
307307de5ddba10bfebab8416a8f79c349faa62bbaa1tom         vg_assert(parser->qparentE[parser->sp].Te.TyStOrUn.fieldRs);
307407de5ddba10bfebab8416a8f79c349faa62bbaa1tom         VG_(addToXA)( parser->qparentE[parser->sp].Te.TyStOrUn.fieldRs,
307507de5ddba10bfebab8416a8f79c349faa62bbaa1tom                       &posn );
307607de5ddba10bfebab8416a8f79c349faa62bbaa1tom         /* And record the child itself */
307707de5ddba10bfebab8416a8f79c349faa62bbaa1tom         goto acquire_Field;
307807de5ddba10bfebab8416a8f79c349faa62bbaa1tom      } else {
307907de5ddba10bfebab8416a8f79c349faa62bbaa1tom         /* Member with no location - this can happen with static
308007de5ddba10bfebab8416a8f79c349faa62bbaa1tom            const members in C++ code which are compile time constants
308107de5ddba10bfebab8416a8f79c349faa62bbaa1tom            that do no exist in the class. They're not of any interest
308207de5ddba10bfebab8416a8f79c349faa62bbaa1tom            to us so we ignore them. */
3083d9df0ea979e3dd5b732b8cced076a105fa45f352philippe         ML_(TyEnt__make_EMPTY)(&fieldE);
3084b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3085b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3086b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3087b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_array_type) {
30889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
30899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = posn;
30909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyArray;
30919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyArray.typeR = D3_INVALID_CUOFF;
30929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyArray.boundRs
30939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ptD.array_type.1",
30949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                       ML_(dinfo_free),
30959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                       sizeof(UWord) );
3096746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
3097b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
3098746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
3099746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
3100746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
3101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
31025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
31035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_type && cts.szB > 0) {
31045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyArray.typeR
31055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = cook_die_using_form( cc, (UWord)cts.u.val, form );
3106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3107b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
31089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (typeE.Te.TyArray.typeR == D3_INVALID_CUOFF)
31095c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
3110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* On't stack! */
31119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typestack_push( cc, parser, td3, &typeE, level );
3112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      goto acquire_Type;
3113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
31152acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   /* this is a subrange type defining the bounds of an array. */
31162acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   if (dtag == DW_TAG_subrange_type
31172acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj       && subrange_type_denotes_array_bounds(parser, dtag)) {
3118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_lower = False;
3119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_upper = False;
3120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_count = False;
3121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Long lower = 0;
3122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Long upper = 0;
3123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      switch (parser->language) {
3125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         case 'C': have_lower = True;  lower = 0; break;
3126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         case 'F': have_lower = True;  lower = 1; break;
3127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         case '?': have_lower = False; break;
31282acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj         case 'A': have_lower = False; break;
3129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         default:  vg_assert(0); /* assured us by handling of
3130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                    DW_TAG_compile_unit in this fn */
3131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
31329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
31339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)( &boundE, 0, sizeof(boundE) );
31349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      boundE.cuOff = D3_INVALID_CUOFF;
31359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      boundE.tag   = Te_Bound;
3136746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
3137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
3138746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
3139746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
3140746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
3141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
31425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
31435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_lower_bound && cts.szB > 0) {
31445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            lower      = (Long)cts.u.val;
3145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_lower = True;
3146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
31475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_upper_bound && cts.szB > 0) {
31485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            upper      = (Long)cts.u.val;
3149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_upper = True;
3150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
31515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_count && cts.szB > 0) {
31525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            /*count    = (Long)cts.u.val;*/
3153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_count = True;
3154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* FIXME: potentially skip the rest if no parent present, since
3157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         it could be the case that this subrange type is free-standing
3158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (not being used to describe the bounds of a containing array
3159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         type) */
3160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have a plausible parent? */
31615c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe      if (typestack_is_empty(parser)) goto_bad_DIE;
31629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
31639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(parser->qparentE[parser->sp].cuOff != D3_INVALID_CUOFF);
31645c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe      if (level != parser->qlevel[parser->sp]+1) goto_bad_DIE;
31655c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe      if (parser->qparentE[parser->sp].tag != Te_TyArray) goto_bad_DIE;
3166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3167b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Figure out if we have a definite range or not */
3168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (have_lower && have_upper && (!have_count)) {
31699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.knownL = True;
31709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.knownU = True;
31719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.boundL = lower;
31729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.boundU = upper;
317372259920f8cad01708271879caca023969463d16tom      }
3174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      else if (have_lower && (!have_upper) && (!have_count)) {
31759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.knownL = True;
31769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.knownU = False;
31779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.boundL = lower;
31789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.boundU = 0;
317972259920f8cad01708271879caca023969463d16tom      }
318072259920f8cad01708271879caca023969463d16tom      else if ((!have_lower) && have_upper && (!have_count)) {
318172259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.knownL = False;
318272259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.knownU = True;
318372259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.boundL = 0;
318472259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.boundU = upper;
318572259920f8cad01708271879caca023969463d16tom      }
318672259920f8cad01708271879caca023969463d16tom      else if ((!have_lower) && (!have_upper) && (!have_count)) {
318772259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.knownL = False;
318872259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.knownU = False;
318972259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.boundL = 0;
319072259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.boundU = 0;
3191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else {
3192b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* FIXME: handle more cases */
31935c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
3194b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Record this bound in the parent */
31979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      boundE.cuOff = posn;
31989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(parser->qparentE[parser->sp].Te.TyArray.boundRs);
31999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(addToXA)( parser->qparentE[parser->sp].Te.TyArray.boundRs,
3200471d6b3eba2d617279c3954a13e322174a0eec13sewardj                    &boundE.cuOff );
3201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* And record the child itself */
32029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      goto acquire_Bound;
3203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
32052acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   /* typedef or subrange_type other than array bounds. */
32062acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   if (dtag == DW_TAG_typedef
32072acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj       || (dtag == DW_TAG_subrange_type
32082acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj           && !subrange_type_denotes_array_bounds(parser, dtag))) {
32092acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      /* subrange_type other than array bound is only for Ada. */
32102acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      vg_assert (dtag == DW_TAG_typedef || parser->language == 'A');
32112acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      /* We can pick up a new typedef/subrange_type any time. */
32129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
32139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = D3_INVALID_CUOFF;
32149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyTyDef;
32159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyTyDef.name = NULL;
32169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyTyDef.typeR = D3_INVALID_CUOFF;
3217746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
3218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
3219746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
3220746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
3221746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
3222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
32235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
32245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
32259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            typeE.Te.TyTyDef.name
32265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = ML_(cur_read_strdup)( cts.u.cur,
32275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       "di.readdwarf3.ptD.typedef.1" );
3228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
32295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_type && cts.szB > 0) {
32305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyTyDef.typeR
32315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = cook_die_using_form( cc, (UWord)cts.u.val, form );
3232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3234e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw      /* Do we have something that looks sane?
3235e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw         gcc gnat Ada generates minimal typedef
3236e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw         such as the below
3237e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw         <6><91cc>: DW_TAG_typedef
3238e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw            DW_AT_abstract_ori: <9066>
3239e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw         g++ for OMP can generate artificial functions that have
3240e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw         parameters that refer to pointers to unnamed typedefs.
3241e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw         See https://bugs.kde.org/show_bug.cgi?id=273475
3242e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw         So we cannot require a name for a DW_TAG_typedef.
3243e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw      */
3244e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw      goto acquire_Type;
3245b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_subroutine_type) {
3248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* function type? just record that one fact and ask no
3249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         further questions. */
32509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
32519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = D3_INVALID_CUOFF;
32529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyFn;
3253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      goto acquire_Type;
3254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_volatile_type || dtag == DW_TAG_const_type) {
3257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int have_ty = 0;
32589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
32599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = D3_INVALID_CUOFF;
32609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyQual;
32619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyQual.qual
3262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         = dtag == DW_TAG_volatile_type ? 'V' : 'C';
3263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* target type defaults to 'void' */
32649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyQual.typeR = D3_FAKEVOID_CUOFF;
3265746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
3266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
3267746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
3268746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
3269746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
3270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
32715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
32725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_type && cts.szB > 0) {
32735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyQual.typeR
32745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = cook_die_using_form( cc, (UWord)cts.u.val, form );
3275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_ty++;
3276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* gcc sometimes generates DW_TAG_const/volatile_type without
3279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT_type and GDB appears to interpret the type as 'const
3280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         void' (resp. 'volatile void').  So just allow it .. */
3281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (have_ty == 1 || have_ty == 0)
3282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto acquire_Type;
3283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      else
32845c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
3285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3287e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart   /*
3288e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart    * Treat DW_TAG_unspecified_type as type void. An example of DW_TAG_unspecified_type:
3289e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart    *
3290e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart    * $ readelf --debug-dump /usr/lib/debug/usr/lib/libstdc++.so.6.0.16.debug
3291e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart    *  <1><10d4>: Abbrev Number: 53 (DW_TAG_unspecified_type)
3292e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart    *     <10d5>   DW_AT_name        : (indirect string, offset: 0xdb7): decltype(nullptr)
3293e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart    */
3294e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart   if (dtag == DW_TAG_unspecified_type) {
3295e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart      VG_(memset)(&typeE, 0, sizeof(typeE));
3296e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart      typeE.cuOff           = D3_INVALID_CUOFF;
3297e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart      typeE.tag             = Te_TyQual;
3298e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart      typeE.Te.TyQual.typeR = D3_FAKEVOID_CUOFF;
3299e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart      goto acquire_Type;
3300e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart   }
3301e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart
3302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* else ignore this DIE */
3303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return;
3304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
3305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  acquire_Type:
3307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (0) VG_(printf)("YYYY Acquire Type\n");
33089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(ML_(TyEnt__is_type)( &typeE ));
33099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(typeE.cuOff == D3_INVALID_CUOFF || typeE.cuOff == posn);
33109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   typeE.cuOff = posn;
33119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(addToXA)( tyents, &typeE );
3312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return;
3313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
3314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  acquire_Atom:
3316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (0) VG_(printf)("YYYY Acquire Atom\n");
33179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(atomE.tag == Te_Atom);
33189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(atomE.cuOff == D3_INVALID_CUOFF || atomE.cuOff == posn);
33199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   atomE.cuOff = posn;
33209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(addToXA)( tyents, &atomE );
3321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return;
3322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
3323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
33249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj  acquire_Field:
3325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* For union members, Expr should be absent */
33269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (0) VG_(printf)("YYYY Acquire Field\n");
33279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(fieldE.tag == Te_Field);
33283c9cf3442185b5891e15450d6e3058aeff6796fetom   vg_assert(fieldE.Te.Field.nLoc <= 0 || fieldE.Te.Field.pos.loc != NULL);
33293c9cf3442185b5891e15450d6e3058aeff6796fetom   vg_assert(fieldE.Te.Field.nLoc != 0 || fieldE.Te.Field.pos.loc == NULL);
33309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (fieldE.Te.Field.isStruct) {
33313c9cf3442185b5891e15450d6e3058aeff6796fetom      vg_assert(fieldE.Te.Field.nLoc != 0);
33329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   } else {
33339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(fieldE.Te.Field.nLoc == 0);
33349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
33359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(fieldE.cuOff == D3_INVALID_CUOFF || fieldE.cuOff == posn);
33369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   fieldE.cuOff = posn;
33379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(addToXA)( tyents, &fieldE );
3338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return;
3339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
3340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
33419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj  acquire_Bound:
33429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (0) VG_(printf)("YYYY Acquire Bound\n");
33439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(boundE.tag == Te_Bound);
33449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(boundE.cuOff == D3_INVALID_CUOFF || boundE.cuOff == posn);
33459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   boundE.cuOff = posn;
33469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(addToXA)( tyents, &boundE );
3347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return;
3348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
3349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  bad_DIE:
3351896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe   dump_bad_die_and_barf("parse_type_DIE", dtag, posn, level,
3352a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                         c_die, saved_die_c_offset,
3353a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                         abbv,
3354a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                         cc);
3355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
3356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
3360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
33619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/*--- Compression of type DIE information                  ---*/
3362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
3363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
3364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
33659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic UWord chase_cuOff ( Bool* changed,
33669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                           XArray* /* of TyEnt */ ents,
33679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                           TyEntIndexCache* ents_cache,
33689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                           UWord cuOff )
33699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
33709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEnt* ent;
33719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache, cuOff );
3372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
33739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (!ent) {
33749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(printf)("chase_cuOff: no entry for 0x%05lx\n", cuOff);
33759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      *changed = False;
33769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      return cuOff;
33779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
337859a2d18d0ddfa241850017252b0804d469187d79sewardj
33799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(ent->tag != Te_EMPTY);
33809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (ent->tag != Te_INDIR) {
33819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      *changed = False;
33829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      return cuOff;
33839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   } else {
33849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ent->Te.INDIR.indR < cuOff);
33859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      *changed = True;
33869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      return ent->Te.INDIR.indR;
3387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
33889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj}
3389b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
33909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic
33919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid chase_cuOffs_in_XArray ( Bool* changed,
33929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                              XArray* /* of TyEnt */ ents,
33939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                              TyEntIndexCache* ents_cache,
33949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                              /*MOD*/XArray* /* of UWord */ cuOffs )
33959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
33969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Bool b2 = False;
33979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Word i, n = VG_(sizeXA)( cuOffs );
33989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   for (i = 0; i < n; i++) {
33999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      Bool   b = False;
34009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      UWord* p = VG_(indexXA)( cuOffs, i );
34019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      *p = chase_cuOff( &b, ents, ents_cache, *p );
34029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (b)
34039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         b2 = True;
34049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
34059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   *changed = b2;
3406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
34089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic Bool TyEnt__subst_R_fields ( XArray* /* of TyEnt */ ents,
34099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                    TyEntIndexCache* ents_cache,
34109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                    /*MOD*/TyEnt* te )
34119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
34129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Bool b, changed = False;
34139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   switch (te->tag) {
34149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_EMPTY:
34159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
34169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_INDIR:
34179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         te->Te.INDIR.indR
34189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = chase_cuOff( &b, ents, ents_cache, te->Te.INDIR.indR );
34199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
34209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
34219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_UNKNOWN:
34229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
34239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_Atom:
34249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
34259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_Field:
34269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         te->Te.Field.typeR
34279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = chase_cuOff( &b, ents, ents_cache, te->Te.Field.typeR );
34289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
34299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
34309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_Bound:
34319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
34329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyBase:
34339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
34340e947cfedebda6da2e84fb61af431db5cf1275fcbart      case Te_TyPtr:
34350e947cfedebda6da2e84fb61af431db5cf1275fcbart      case Te_TyRef:
34360e947cfedebda6da2e84fb61af431db5cf1275fcbart      case Te_TyPtrMbr:
34370e947cfedebda6da2e84fb61af431db5cf1275fcbart      case Te_TyRvalRef:
34389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         te->Te.TyPorR.typeR
34399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = chase_cuOff( &b, ents, ents_cache, te->Te.TyPorR.typeR );
34409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
34419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
34429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyTyDef:
34439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         te->Te.TyTyDef.typeR
34449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = chase_cuOff( &b, ents, ents_cache, te->Te.TyTyDef.typeR );
34459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
34469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
34479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyStOrUn:
34489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyStOrUn.fieldRs );
34499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
34509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
34519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyEnum:
34529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyEnum.atomRs );
34539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
34549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
34559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyArray:
34569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         te->Te.TyArray.typeR
34579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = chase_cuOff( &b, ents, ents_cache, te->Te.TyArray.typeR );
34589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
34599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyArray.boundRs );
34609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
34619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
34629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyFn:
34639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
34649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyQual:
34659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         te->Te.TyQual.typeR
34669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = chase_cuOff( &b, ents, ents_cache, te->Te.TyQual.typeR );
34679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
34689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
34699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyVoid:
34709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
34719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      default:
34729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ML_(pp_TyEnt)(te);
34739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(0);
34749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
34759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   return changed;
34769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj}
347759a2d18d0ddfa241850017252b0804d469187d79sewardj
34789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Make a pass over 'ents'.  For each tyent, inspect the target of any
34799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   'R' or 'Rs' fields (those which refer to other tyents), and replace
34809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   any which point to INDIR nodes with the target of the indirection
34819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   (which should not itself be an indirection).  In summary, this
34829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   routine shorts out all references to indirection nodes. */
34839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic
34849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjWord dedup_types_substitution_pass ( /*MOD*/XArray* /* of TyEnt */ ents,
34859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                     TyEntIndexCache* ents_cache )
34869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
34879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Word i, n, nChanged = 0;
34889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Bool b;
34899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   n = VG_(sizeXA)( ents );
34909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   for (i = 0; i < n; i++) {
34919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TyEnt* ent = VG_(indexXA)( ents, i );
34929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ent->tag != Te_EMPTY);
34939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* We have to substitute everything, even indirections, so as to
34949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ensure that chains of indirections don't build up. */
34959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      b = TyEnt__subst_R_fields( ents, ents_cache, ent );
34969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (b)
34979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         nChanged++;
34989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
349959a2d18d0ddfa241850017252b0804d469187d79sewardj
35009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   return nChanged;
35019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj}
350259a2d18d0ddfa241850017252b0804d469187d79sewardj
350359a2d18d0ddfa241850017252b0804d469187d79sewardj
35049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Make a pass over 'ents', building a dictionary of TyEnts as we go.
35059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Look up each new tyent in the dictionary in turn.  If it is already
35069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   in the dictionary, replace this tyent with an indirection to the
35079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   existing one, and delete any malloc'd stuff hanging off this one.
35089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   In summary, this routine commons up all tyents that are identical
35099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   as defined by TyEnt__cmp_by_all_except_cuOff. */
35109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic
35119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjWord dedup_types_commoning_pass ( /*MOD*/XArray* /* of TyEnt */ ents )
3512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
35139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Word    n, i, nDeleted;
35149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   WordFM* dict; /* TyEnt* -> void */
35159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEnt*  ent;
35169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   UWord   keyW, valW;
35179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
35189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   dict = VG_(newFM)(
35199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj             ML_(dinfo_zalloc), "di.readdwarf3.dtcp.1",
35209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj             ML_(dinfo_free),
35219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj             (Word(*)(UWord,UWord)) ML_(TyEnt__cmp_by_all_except_cuOff)
35229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj          );
35239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
35249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   nDeleted = 0;
35259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   n = VG_(sizeXA)( ents );
35269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   for (i = 0; i < n; i++) {
35279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      ent = VG_(indexXA)( ents, i );
35289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ent->tag != Te_EMPTY);
35299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
35309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* Ignore indirections, although check that they are
35319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         not forming a cycle. */
35329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (ent->tag == Te_INDIR) {
35339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(ent->Te.INDIR.indR < ent->cuOff);
35349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         continue;
35359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      }
3536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
35379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      keyW = valW = 0;
35389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (VG_(lookupFM)( dict, &keyW, &valW, (UWord)ent )) {
35399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         /* it's already in the dictionary. */
35409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         TyEnt* old = (TyEnt*)keyW;
35419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(valW == 0);
35429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(old != ent);
35439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(old->tag != Te_INDIR);
35449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         /* since we are traversing the array in increasing order of
35459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            cuOff: */
35469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(old->cuOff < ent->cuOff);
35479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         /* So anyway, dump this entry and replace it with an
35489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            indirection to the one in the dictionary.  Note that the
35499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            assertion above guarantees that we cannot create cycles of
35509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            indirections, since we are always creating an indirection
35519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            to a tyent with a cuOff lower than this one. */
35529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ML_(TyEnt__make_EMPTY)( ent );
35539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ent->tag = Te_INDIR;
35549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ent->Te.INDIR.indR = old->cuOff;
35559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         nDeleted++;
35569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      } else {
35579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         /* not in dictionary; add it and keep going. */
35589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         VG_(addToFM)( dict, (UWord)ent, 0 );
35599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      }
35609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
35619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
35629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(deleteFM)( dict, NULL, NULL );
356359a2d18d0ddfa241850017252b0804d469187d79sewardj
35649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   return nDeleted;
35659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj}
3566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
35689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic
35699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid dedup_types ( Bool td3,
35709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                   /*MOD*/XArray* /* of TyEnt */ ents,
35719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                   TyEntIndexCache* ents_cache )
35729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
35739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Word m, n, i, nDel, nSubst, nThresh;
35749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (0) td3 = True;
35759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
35769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   n = VG_(sizeXA)( ents );
35779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
35789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* If a commoning pass and a substitution pass both make fewer than
35799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      this many changes, just stop.  It's pointless to burn up CPU
35809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      time trying to compress the last 1% or so out of the array. */
35819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   nThresh = n / 200;
35829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
35839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* First we must sort .ents by its .cuOff fields, so we
35849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      can index into it. */
35856bd9dc18c043927c1196caba20a327238a179c42florian   VG_(setCmpFnXA)( ents, (XACmpFn_t) ML_(TyEnt__cmp_by_cuOff_only) );
35869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(sortXA)( ents );
35879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
35889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* Now repeatedly do commoning and substitution passes over
35899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      the array, until there are no more changes. */
35909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   do {
35919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      nDel   = dedup_types_commoning_pass ( ents );
35929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      nSubst = dedup_types_substitution_pass ( ents, ents_cache );
35939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(nDel >= 0 && nSubst >= 0);
35949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TRACE_D3("   %ld deletions, %ld substitutions\n", nDel, nSubst);
35959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   } while (nDel > nThresh || nSubst > nThresh);
35969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
35979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* Sanity check: all INDIR nodes should point at a non-INDIR thing.
35989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      In fact this should be true at the end of every loop iteration
35999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      above (a commoning pass followed by a substitution pass), but
36009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      checking it on every iteration is excessively expensive.  Note,
36019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      this loop also computes 'm' for the stats printing below it. */
36029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   m = 0;
36039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   n = VG_(sizeXA)( ents );
360459a2d18d0ddfa241850017252b0804d469187d79sewardj   for (i = 0; i < n; i++) {
36059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TyEnt *ent, *ind;
36069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      ent = VG_(indexXA)( ents, i );
36079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (ent->tag != Te_INDIR) continue;
36089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      m++;
36099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      ind = ML_(TyEnts__index_by_cuOff)( ents, ents_cache,
36109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                         ent->Te.INDIR.indR );
36119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ind);
36129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ind->tag != Te_INDIR);
3613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
36159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TRACE_D3("Overall: %ld before, %ld after\n", n, n-m);
36169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj}
36179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
36189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
36199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/*------------------------------------------------------------*/
36209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/*---                                                      ---*/
36219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/*--- Resolution of references to type DIEs                ---*/
36229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/*---                                                      ---*/
36239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/*------------------------------------------------------------*/
36249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
36259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Make a pass through the (temporary) variables array.  Examine the
36269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   type of each variable, check is it found, and chase any Te_INDIRs.
36279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Postcondition is: each variable has a typeR field that refers to a
36289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   valid type in tyents, or a Te_UNKNOWN, and is certainly guaranteed
36299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   not to refer to a Te_INDIR.  (This is so that we can throw all the
36309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Te_INDIRs away later). */
36319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
36329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj__attribute__((noinline))
36339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic void resolve_variable_types (
36346bd9dc18c043927c1196caba20a327238a179c42florian               void (*barf)( const HChar* ) __attribute__((noreturn)),
36359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               /*R-O*/XArray* /* of TyEnt */ ents,
36369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               /*MOD*/TyEntIndexCache* ents_cache,
36379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               /*MOD*/XArray* /* of TempVar* */ vars
36389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            )
36399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
36409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Word i, n;
364159a2d18d0ddfa241850017252b0804d469187d79sewardj   n = VG_(sizeXA)( vars );
364259a2d18d0ddfa241850017252b0804d469187d79sewardj   for (i = 0; i < n; i++) {
364359a2d18d0ddfa241850017252b0804d469187d79sewardj      TempVar* var = *(TempVar**)VG_(indexXA)( vars, i );
36449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* This is the stated type of the variable.  But it might be
36459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         an indirection, so be careful. */
36469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TyEnt* ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache,
36479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                                var->typeR );
36489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (ent && ent->tag == Te_INDIR) {
36499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache,
36509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                            ent->Te.INDIR.indR );
36519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(ent);
36529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(ent->tag != Te_INDIR);
36539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      }
3654b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
36559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* Deal first with "normal" cases */
36569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (ent && ML_(TyEnt__is_type)(ent)) {
36579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         var->typeR = ent->cuOff;
36589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         continue;
36599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      }
36609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
36619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* If there's no ent, it probably we did not manage to read a
36629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         type at the cuOffset which is stated as being this variable's
36639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         type.  Maybe a deficiency in parse_type_DIE.  Complain. */
36649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (ent == NULL) {
36659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         VG_(printf)("\n: Invalid cuOff = 0x%05lx\n", var->typeR );
36669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         barf("resolve_variable_types: "
36679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj              "cuOff does not refer to a known type");
36689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      }
36699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ent);
36709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* If ent has any other tag, something bad happened, along the
36719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         lines of var->typeR not referring to a type at all. */
36729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ent->tag == Te_UNKNOWN);
36739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* Just accept it; the type will be useless, but at least keep
36749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         going. */
36759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      var->typeR = ent->cuOff;
3676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
3681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
3682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Parsing of Compilation Units                         ---*/
3683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
3684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
3685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
36866bd9dc18c043927c1196caba20a327238a179c42florianstatic Int cmp_TempVar_by_dioff ( const void* v1, const void* v2 ) {
36873e7986312a0ffc7646b0552d4c4ea3744a870e73florian   const TempVar* t1 = *(const TempVar *const *)v1;
36883e7986312a0ffc7646b0552d4c4ea3744a870e73florian   const TempVar* t2 = *(const TempVar *const *)v2;
3689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (t1->dioff < t2->dioff) return -1;
3690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (t1->dioff > t2->dioff) return 1;
3691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return 0;
3692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
36949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic void read_DIE (
36959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/WordFM* /* of (XArray* of AddrRange, void) */ rangestree,
36969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/XArray* /* of TyEnt */ tyents,
36979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/XArray* /* of TempVar* */ tempvars,
36989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/XArray* /* of GExpr* */ gexprs,
36999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/D3TypeParser* typarser,
37009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/D3VarParser* varparser,
3701a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   /*MOD*/D3InlParser* inlparser,
37029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Cursor* c, Bool td3, CUConst* cc, Int level
37039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj)
3704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
3705746e97e7098def65d59c79d5d661f9a757a837cdphilippe   g_abbv *abbv;
3706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ULong  atag, abbv_code;
3707746e97e7098def65d59c79d5d661f9a757a837cdphilippe   UInt   nf_i;
3708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UWord  posn;
3709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt   has_children;
3710746e97e7098def65d59c79d5d661f9a757a837cdphilippe   UWord  start_die_c_offset;
3711746e97e7098def65d59c79d5d661f9a757a837cdphilippe   UWord  after_die_c_offset;
3712a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   // If the DIE we will parse has a sibling and the parser(s) are
3713a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   // all indicating that parse_children is not necessary, then
3714a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   // we will skip the children by jumping to the sibling of this DIE
3715a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   // (if it has a sibling).
3716a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UWord  sibling = 0;
3717a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Bool   parse_children = False;
3718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* --- Deal with this DIE --- */
3720d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   posn      = cook_die( cc, get_position_of_Cursor( c ) );
3721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   abbv_code = get_ULEB128( c );
3722746e97e7098def65d59c79d5d661f9a757a837cdphilippe   abbv = get_abbv(cc, abbv_code);
3723746e97e7098def65d59c79d5d661f9a757a837cdphilippe   atag      = abbv->atag;
3724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3("\n");
3725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3(" <%d><%lx>: Abbrev Number: %llu (%s)\n",
3726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            level, posn, abbv_code, ML_(pp_DW_TAG)( atag ) );
3727b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (atag == 0)
3729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("read_DIE: invalid zero tag on DIE");
3730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3731746e97e7098def65d59c79d5d661f9a757a837cdphilippe   has_children = abbv->has_children;
3732b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (has_children != DW_children_no && has_children != DW_children_yes)
3733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("read_DIE: invalid has_children value");
3734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* We're set up to look at the fields of this DIE.  Hand it off to
3736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      any parser(s) that want to see it.  Since they will in general
37370d2ea9d1cfd6f1fff0992096c2d15881becfe2e1philippe      advance the DIE cursor, remember the current settings so that we
37380d2ea9d1cfd6f1fff0992096c2d15881becfe2e1philippe      can then back up and do one final pass over the DIE, to print out
37390d2ea9d1cfd6f1fff0992096c2d15881becfe2e1philippe      its contents. */
3740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   start_die_c_offset  = get_position_of_Cursor( c );
3741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3742896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe   /* "pre-read" the DIE (while doing nothing with the data)
3743896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe      for 3 reasons:
3744896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe        1. it td3, trace the DIE data.
3745896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe        2. determine if this DIE has a sibling (used for
3746896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe           optimising when only reading the inline info).
3747896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe        3. determine the end of the DIE (after_die_c_offset).
3748896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe
3749896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe      The parsers below will re-read the DIEs if they are interested
3750896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe      in the atag.  The var/type parsers re-read many DIEs.  The
3751896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe      inline parser re-reads a smaller subset.
3752896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe      We could possibly avoid this double reading by having each
3753896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe      parser optionally parse the DIE and (if needed) skip
3754896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe      the DIE data if it was not read by any parser. */
3755746e97e7098def65d59c79d5d661f9a757a837cdphilippe   nf_i = 0;
3756b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
37575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      FormContents cts;
3758746e97e7098def65d59c79d5d661f9a757a837cdphilippe      ULong at_name = abbv->nf[nf_i].at_name;
3759746e97e7098def65d59c79d5d661f9a757a837cdphilippe      ULong at_form = abbv->nf[nf_i].at_form;
3760746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i++;
3761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (at_name == 0 && at_form == 0) break;
3762b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("     %18s: ", ML_(pp_DW_AT)(at_name));
3763b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Get the form contents, but ignore them; the only purpose is
3764b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         to print them, if td3 is True */
37655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      get_Form_contents( &cts, cc, c, td3, (DW_FORM)at_form );
3766a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Except that we remember if this DIE has a sibling. */
3767a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (UNLIKELY(at_name == DW_AT_sibling && cts.szB > 0)) {
3768a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         sibling = cts.u.val;
3769a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
3770b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("\t");
3771b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("\n");
3772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   after_die_c_offset  = get_position_of_Cursor( c );
3774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3775a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (VG_(clo_read_var_info)) {
3776a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      set_position_of_Cursor( c,     start_die_c_offset );
3777a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
3778a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      parse_type_DIE( tyents,
3779a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      typarser,
3780a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      (DW_TAG)atag,
3781a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      posn,
3782a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      level,
3783a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      c,     /* DIE cursor */
3784a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      abbv,  /* abbrev */
3785a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      cc,
3786a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      td3 );
3787a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
3788a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      set_position_of_Cursor( c,     start_die_c_offset );
3789a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
3790a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      parse_var_DIE( rangestree,
3791a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     tempvars,
3792a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     gexprs,
3793a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     varparser,
3794a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     (DW_TAG)atag,
3795a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     posn,
3796a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     level,
3797a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     c,     /* DIE cursor */
3798a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     abbv,  /* abbrev */
3799a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     cc,
3800a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     td3 );
3801a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
3802a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      parse_children = True;
3803a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      // type and var parsers do not have logic to skip childrens.
3804a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
3805a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
3806a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (VG_(clo_read_inline_info)) {
3807a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      set_position_of_Cursor( c,     start_die_c_offset );
3808a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
3809a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      parse_children =
3810a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         parse_inl_DIE( inlparser,
3811a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        (DW_TAG)atag,
3812a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        posn,
3813a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        level,
3814a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        c,     /* DIE cursor */
3815a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        abbv, /* abbrev */
3816a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        cc,
3817a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        td3 )
3818a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         || parse_children;
3819a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
3820b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3821b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   set_position_of_Cursor( c,     after_die_c_offset );
3822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3823a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   /* --- Now recurse into its children, if any
3824a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      and the parsing of the children is requested by a parser --- */
3825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (has_children == DW_children_yes) {
3826a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (parse_children || sibling == 0) {
3827a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (0) TRACE_D3("BEGIN children of level %d\n", level);
3828a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         while (True) {
3829a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            atag = peek_ULEB128( c );
3830a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (atag == 0) break;
3831a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            read_DIE( rangestree, tyents, tempvars, gexprs,
3832a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      typarser, varparser, inlparser,
3833a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      c, td3, cc, level+1 );
3834a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
3835a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* Now we need to eat the terminating zero */
3836a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         atag = get_ULEB128( c );
3837a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         vg_assert(atag == 0);
3838a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (0) TRACE_D3("END children of level %d\n", level);
3839a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      } else {
3840a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         // We can skip the childrens, by jumping to the sibling
3841a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         TRACE_D3("SKIPPING DIE's children,"
3842a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                  "jumping to sibling <%d><%lx>\n",
3843a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                  level, sibling);
3844a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         set_position_of_Cursor( c, sibling );
3845b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3846b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3849b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3850c9831572483ed485438553d4c39686605d2625d6philippestatic void trace_debug_loc (struct _DebugInfo* di,
3851c9831572483ed485438553d4c39686605d2625d6philippe                             __attribute__((noreturn)) void (*barf)( const HChar* ),
3852c9831572483ed485438553d4c39686605d2625d6philippe                             DiSlice escn_debug_loc)
3853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
3854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#if 0
3855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* This doesn't work properly because it assumes all entries are
3856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      packed end to end, with no holes.  But that doesn't always
3857b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      appear to be the case, so it loses sync.  And the D3 spec
3858b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      doesn't appear to require a no-hole situation either. */
3859b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Display .debug_loc */
3860b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Addr  dl_base;
3861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UWord dl_offset;
3862b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Cursor loc; /* for showing .debug_loc */
3863c9831572483ed485438553d4c39686605d2625d6philippe   Bool td3 = di->trace_symtab;
3864c9831572483ed485438553d4c39686605d2625d6philippe
3865b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n");
3866b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n------ The contents of .debug_loc ------\n");
3867b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("    Offset   Begin    End      Expression\n");
3868c9831572483ed485438553d4c39686605d2625d6philippe   if (ML_(sli_is_valid)(escn_debug_loc)) {
3869c9831572483ed485438553d4c39686605d2625d6philippe      init_Cursor( &loc, escn_debug_loc, 0, barf,
3870c9831572483ed485438553d4c39686605d2625d6philippe                   "Overrun whilst reading .debug_loc section(1)" );
3871c9831572483ed485438553d4c39686605d2625d6philippe      dl_base = 0;
3872c9831572483ed485438553d4c39686605d2625d6philippe      dl_offset = 0;
3873c9831572483ed485438553d4c39686605d2625d6philippe      while (True) {
3874c9831572483ed485438553d4c39686605d2625d6philippe         UWord  w1, w2;
3875c9831572483ed485438553d4c39686605d2625d6philippe         UWord  len;
3876c9831572483ed485438553d4c39686605d2625d6philippe         if (is_at_end_Cursor( &loc ))
3877c9831572483ed485438553d4c39686605d2625d6philippe            break;
3878b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3879c9831572483ed485438553d4c39686605d2625d6philippe         /* Read a (host-)word pair.  This is something of a hack since
3880c9831572483ed485438553d4c39686605d2625d6philippe            the word size to read is really dictated by the ELF file;
3881c9831572483ed485438553d4c39686605d2625d6philippe            however, we assume we're reading a file with the same
3882c9831572483ed485438553d4c39686605d2625d6philippe            word-sizeness as the host.  Reasonably enough. */
3883c9831572483ed485438553d4c39686605d2625d6philippe         w1 = get_UWord( &loc );
3884c9831572483ed485438553d4c39686605d2625d6philippe         w2 = get_UWord( &loc );
3885b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3886c9831572483ed485438553d4c39686605d2625d6philippe         if (w1 == 0 && w2 == 0) {
3887c9831572483ed485438553d4c39686605d2625d6philippe            /* end of list.  reset 'base' */
3888c9831572483ed485438553d4c39686605d2625d6philippe            TRACE_D3("    %08lx <End of list>\n", dl_offset);
3889c9831572483ed485438553d4c39686605d2625d6philippe            dl_base = 0;
3890c9831572483ed485438553d4c39686605d2625d6philippe            dl_offset = get_position_of_Cursor( &loc );
3891c9831572483ed485438553d4c39686605d2625d6philippe            continue;
3892c9831572483ed485438553d4c39686605d2625d6philippe         }
3893b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3894c9831572483ed485438553d4c39686605d2625d6philippe         if (w1 == -1UL) {
3895c9831572483ed485438553d4c39686605d2625d6philippe            /* new value for 'base' */
3896c9831572483ed485438553d4c39686605d2625d6philippe            TRACE_D3("    %08lx %16lx %08lx (base address)\n",
3897c9831572483ed485438553d4c39686605d2625d6philippe                     dl_offset, w1, w2);
3898c9831572483ed485438553d4c39686605d2625d6philippe            dl_base = w2;
3899c9831572483ed485438553d4c39686605d2625d6philippe            continue;
3900c9831572483ed485438553d4c39686605d2625d6philippe         }
3901c9831572483ed485438553d4c39686605d2625d6philippe
3902c9831572483ed485438553d4c39686605d2625d6philippe         /* else a location expression follows */
3903c9831572483ed485438553d4c39686605d2625d6philippe         TRACE_D3("    %08lx %08lx %08lx ",
3904c9831572483ed485438553d4c39686605d2625d6philippe                  dl_offset, w1 + dl_base, w2 + dl_base);
3905c9831572483ed485438553d4c39686605d2625d6philippe         len = (UWord)get_UShort( &loc );
3906c9831572483ed485438553d4c39686605d2625d6philippe         while (len > 0) {
3907c9831572483ed485438553d4c39686605d2625d6philippe            UChar byte = get_UChar( &loc );
3908c9831572483ed485438553d4c39686605d2625d6philippe            TRACE_D3("%02x", (UInt)byte);
3909c9831572483ed485438553d4c39686605d2625d6philippe            len--;
3910c9831572483ed485438553d4c39686605d2625d6philippe         }
3911c9831572483ed485438553d4c39686605d2625d6philippe         TRACE_SYMTAB("\n");
3912b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3914b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
3915c9831572483ed485438553d4c39686605d2625d6philippe}
3916c9831572483ed485438553d4c39686605d2625d6philippe
3917c9831572483ed485438553d4c39686605d2625d6philippestatic void trace_debug_ranges (struct _DebugInfo* di,
3918c9831572483ed485438553d4c39686605d2625d6philippe                                __attribute__((noreturn)) void (*barf)( const HChar* ),
3919c9831572483ed485438553d4c39686605d2625d6philippe                                DiSlice escn_debug_ranges)
3920c9831572483ed485438553d4c39686605d2625d6philippe{
3921c9831572483ed485438553d4c39686605d2625d6philippe   Cursor ranges; /* for showing .debug_ranges */
3922c9831572483ed485438553d4c39686605d2625d6philippe   Addr  dr_base;
3923c9831572483ed485438553d4c39686605d2625d6philippe   UWord dr_offset;
3924c9831572483ed485438553d4c39686605d2625d6philippe   Bool td3 = di->trace_symtab;
3925b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3926b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Display .debug_ranges */
3927b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n");
3928b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n------ The contents of .debug_ranges ------\n");
3929b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("    Offset   Begin    End\n");
39305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (ML_(sli_is_valid)(escn_debug_ranges)) {
39315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      init_Cursor( &ranges, escn_debug_ranges, 0, barf,
39325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                   "Overrun whilst reading .debug_ranges section(1)" );
39335d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      dr_base = 0;
39345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      dr_offset = 0;
39355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      while (True) {
39365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UWord  w1, w2;
3937b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
39385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (is_at_end_Cursor( &ranges ))
39395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            break;
3940b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
39415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         /* Read a (host-)word pair.  This is something of a hack since
39425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            the word size to read is really dictated by the ELF file;
39435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            however, we assume we're reading a file with the same
39445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            word-sizeness as the host.  Reasonably enough. */
39455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         w1 = get_UWord( &ranges );
39465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         w2 = get_UWord( &ranges );
39475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
39485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (w1 == 0 && w2 == 0) {
39495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            /* end of list.  reset 'base' */
39505d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            TRACE_D3("    %08lx <End of list>\n", dr_offset);
39515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            dr_base = 0;
39525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            dr_offset = get_position_of_Cursor( &ranges );
39535d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            continue;
39545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
3955b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
39565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (w1 == -1UL) {
39575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            /* new value for 'base' */
39585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            TRACE_D3("    %08lx %16lx %08lx (base address)\n",
39595d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                     dr_offset, w1, w2);
39605d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            dr_base = w2;
39615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            continue;
39625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
3963b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
39645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         /* else a range [w1+base, w2+base) is denoted */
39655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("    %08lx %08lx %08lx\n",
39665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  dr_offset, w1 + dr_base, w2 + dr_base);
3967b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3968b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3969c9831572483ed485438553d4c39686605d2625d6philippe}
3970c9831572483ed485438553d4c39686605d2625d6philippe
3971c9831572483ed485438553d4c39686605d2625d6philippestatic void trace_debug_abbrev (struct _DebugInfo* di,
3972c9831572483ed485438553d4c39686605d2625d6philippe                                __attribute__((noreturn)) void (*barf)( const HChar* ),
3973c9831572483ed485438553d4c39686605d2625d6philippe                                DiSlice escn_debug_abbv)
3974c9831572483ed485438553d4c39686605d2625d6philippe{
3975c9831572483ed485438553d4c39686605d2625d6philippe   Cursor abbv; /* for showing .debug_abbrev */
3976c9831572483ed485438553d4c39686605d2625d6philippe   Bool td3 = di->trace_symtab;
3977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3978b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Display .debug_abbrev */
3979b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n");
3980b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n------ The contents of .debug_abbrev ------\n");
39815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (ML_(sli_is_valid)(escn_debug_abbv)) {
39825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      init_Cursor( &abbv, escn_debug_abbv, 0, barf,
39835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                   "Overrun whilst reading .debug_abbrev section" );
3984b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
39855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (is_at_end_Cursor( &abbv ))
39865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            break;
39875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         /* Read one abbreviation table */
39885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("  Number TAG\n");
3989b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while (True) {
39905d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ULong atag;
39915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            UInt  has_children;
39925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ULong acode = get_ULEB128( &abbv );
39935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            if (acode == 0) break; /* end of the table */
39945d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            atag = get_ULEB128( &abbv );
39955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            has_children = get_UChar( &abbv );
39965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            TRACE_D3("   %llu      %s    [%s]\n",
39975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                     acode, ML_(pp_DW_TAG)(atag),
39985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                            ML_(pp_DW_children)(has_children));
39995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            while (True) {
40005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               ULong at_name = get_ULEB128( &abbv );
40015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               ULong at_form = get_ULEB128( &abbv );
40025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               if (at_name == 0 && at_form == 0) break;
40035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               TRACE_D3("    %18s %s\n",
40045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                        ML_(pp_DW_AT)(at_name), ML_(pp_DW_FORM)(at_form));
40055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            }
4006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
4007b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4009c9831572483ed485438553d4c39686605d2625d6philippe}
4010c9831572483ed485438553d4c39686605d2625d6philippe
4011c9831572483ed485438553d4c39686605d2625d6philippestatic
4012c9831572483ed485438553d4c39686605d2625d6philippevoid new_dwarf3_reader_wrk (
4013c9831572483ed485438553d4c39686605d2625d6philippe   struct _DebugInfo* di,
4014c9831572483ed485438553d4c39686605d2625d6philippe   __attribute__((noreturn)) void (*barf)( const HChar* ),
4015c9831572483ed485438553d4c39686605d2625d6philippe   DiSlice escn_debug_info,      DiSlice escn_debug_types,
4016c9831572483ed485438553d4c39686605d2625d6philippe   DiSlice escn_debug_abbv,      DiSlice escn_debug_line,
4017c9831572483ed485438553d4c39686605d2625d6philippe   DiSlice escn_debug_str,       DiSlice escn_debug_ranges,
4018c9831572483ed485438553d4c39686605d2625d6philippe   DiSlice escn_debug_loc,       DiSlice escn_debug_info_alt,
4019c9831572483ed485438553d4c39686605d2625d6philippe   DiSlice escn_debug_abbv_alt,  DiSlice escn_debug_line_alt,
4020c9831572483ed485438553d4c39686605d2625d6philippe   DiSlice escn_debug_str_alt
4021c9831572483ed485438553d4c39686605d2625d6philippe)
4022c9831572483ed485438553d4c39686605d2625d6philippe{
4023c9831572483ed485438553d4c39686605d2625d6philippe   XArray* /* of TyEnt */     tyents = NULL;
4024c9831572483ed485438553d4c39686605d2625d6philippe   XArray* /* of TyEnt */     tyents_to_keep = NULL;
4025c9831572483ed485438553d4c39686605d2625d6philippe   XArray* /* of GExpr* */    gexprs = NULL;
4026c9831572483ed485438553d4c39686605d2625d6philippe   XArray* /* of TempVar* */  tempvars = NULL;
4027c9831572483ed485438553d4c39686605d2625d6philippe   WordFM* /* of (XArray* of AddrRange, void) */ rangestree = NULL;
4028c9831572483ed485438553d4c39686605d2625d6philippe   TyEntIndexCache* tyents_cache = NULL;
4029c9831572483ed485438553d4c39686605d2625d6philippe   TyEntIndexCache* tyents_to_keep_cache = NULL;
4030c9831572483ed485438553d4c39686605d2625d6philippe   TempVar *varp, *varp2;
4031c9831572483ed485438553d4c39686605d2625d6philippe   GExpr* gexpr;
4032c9831572483ed485438553d4c39686605d2625d6philippe   Cursor info; /* primary cursor for parsing .debug_info */
4033c9831572483ed485438553d4c39686605d2625d6philippe   D3TypeParser typarser;
4034c9831572483ed485438553d4c39686605d2625d6philippe   D3VarParser varparser;
4035c9831572483ed485438553d4c39686605d2625d6philippe   D3InlParser inlparser;
4036c9831572483ed485438553d4c39686605d2625d6philippe   Word  i, j, n;
4037c9831572483ed485438553d4c39686605d2625d6philippe   Bool td3 = di->trace_symtab;
4038c9831572483ed485438553d4c39686605d2625d6philippe   XArray* /* of TempVar* */ dioff_lookup_tab;
4039c9831572483ed485438553d4c39686605d2625d6philippe   Int pass;
4040c9831572483ed485438553d4c39686605d2625d6philippe   VgHashTable signature_types = NULL;
4041c9831572483ed485438553d4c39686605d2625d6philippe
4042c9831572483ed485438553d4c39686605d2625d6philippe   /* Display/trace various information, if requested. */
4043c9831572483ed485438553d4c39686605d2625d6philippe   if (td3) {
4044c9831572483ed485438553d4c39686605d2625d6philippe      trace_debug_loc    (di, barf, escn_debug_loc);
4045c9831572483ed485438553d4c39686605d2625d6philippe      trace_debug_ranges (di, barf, escn_debug_ranges);
4046c9831572483ed485438553d4c39686605d2625d6philippe      trace_debug_abbrev (di, barf, escn_debug_abbv);
4047c9831572483ed485438553d4c39686605d2625d6philippe      TRACE_SYMTAB("\n");
4048c9831572483ed485438553d4c39686605d2625d6philippe   }
4049c9831572483ed485438553d4c39686605d2625d6philippe
4050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4051a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (VG_(clo_read_var_info)) {
4052a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* We'll park the harvested type information in here.  Also create
4053a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         a fake "void" entry with offset D3_FAKEVOID_CUOFF, so we always
4054a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         have at least one type entry to refer to.  D3_FAKEVOID_CUOFF is
4055a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         huge and presumably will not occur in any valid DWARF3 file --
4056a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         it would need to have a .debug_info section 4GB long for that to
4057a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         happen.  These type entries end up in the DebugInfo. */
4058a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      tyents = VG_(newXA)( ML_(dinfo_zalloc),
4059a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                           "di.readdwarf3.ndrw.1 (TyEnt temp array)",
4060a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                           ML_(dinfo_free), sizeof(TyEnt) );
4061a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      { TyEnt tyent;
4062a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe        VG_(memset)(&tyent, 0, sizeof(tyent));
4063a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe        tyent.tag   = Te_TyVoid;
4064a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe        tyent.cuOff = D3_FAKEVOID_CUOFF;
4065a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe        tyent.Te.TyVoid.isFake = True;
4066a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe        VG_(addToXA)( tyents, &tyent );
4067a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
4068a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      { TyEnt tyent;
4069a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe        VG_(memset)(&tyent, 0, sizeof(tyent));
4070a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe        tyent.tag   = Te_UNKNOWN;
4071a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe        tyent.cuOff = D3_INVALID_CUOFF;
4072a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe        VG_(addToXA)( tyents, &tyent );
4073a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
4074a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4075a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* This is a tree used to unique-ify the range lists that are
4076a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         manufactured by parse_var_DIE.  References to the keys in the
4077a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         tree wind up in .rngMany fields in TempVars.  We'll need to
4078a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         delete this tree, and the XArrays attached to it, at the end of
4079a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         this function. */
4080a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      rangestree = VG_(newFM)( ML_(dinfo_zalloc),
4081a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                               "di.readdwarf3.ndrw.2 (rangestree)",
4082a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                               ML_(dinfo_free),
4083a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                               (Word(*)(UWord,UWord))cmp__XArrays_of_AddrRange );
4084a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4085a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* List of variables we're accumulating.  These don't end up in the
4086a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         DebugInfo; instead their contents are handed to ML_(addVar) and
4087a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         the list elements are then deleted. */
4088a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      tempvars = VG_(newXA)( ML_(dinfo_zalloc),
4089a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             "di.readdwarf3.ndrw.3 (TempVar*s array)",
4090a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             ML_(dinfo_free),
4091a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             sizeof(TempVar*) );
4092a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4093a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* List of GExprs we're accumulating.  These wind up in the
4094a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         DebugInfo. */
4095a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      gexprs = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.4",
4096a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                           ML_(dinfo_free), sizeof(GExpr*) );
4097a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4098a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* We need a D3TypeParser to keep track of partially constructed
4099a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         types.  It'll be discarded as soon as we've completed the CU,
4100a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         since the resulting information is tipped in to 'tyents' as it
4101a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         is generated. */
4102a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(memset)( &typarser, 0, sizeof(typarser) );
4103a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      typarser.sp = -1;
4104a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      typarser.language = '?';
4105a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      for (i = 0; i < N_D3_TYPE_STACK; i++) {
4106a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         typarser.qparentE[i].tag   = Te_EMPTY;
4107a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         typarser.qparentE[i].cuOff = D3_INVALID_CUOFF;
4108a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
41099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
4110a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(memset)( &varparser, 0, sizeof(varparser) );
4111a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      varparser.sp = -1;
4112a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4113a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      signature_types = VG_(HT_construct) ("signature_types");
41149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
4115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4116a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (VG_(clo_read_inline_info))
4117a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe       VG_(memset)( &inlparser, 0, sizeof(inlparser) );
4118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4119d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   /* Do an initial pass to scan the .debug_types section, if any, and
4120d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      fill in the signatured types hash table.  This lets us handle
4121d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      mapping from a type signature to a (cooked) DIE offset directly
4122d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      in get_Form_contents.  */
4123a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (VG_(clo_read_var_info) && ML_(sli_is_valid)(escn_debug_types)) {
41245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      init_Cursor( &info, escn_debug_types, 0, barf,
4125d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                   "Overrun whilst reading .debug_types section" );
41265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      TRACE_D3("\n------ Collecting signatures from "
41275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               ".debug_types section ------\n");
4128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4129d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      while (True) {
4130d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         UWord   cu_start_offset, cu_offset_now;
4131d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         CUConst cc;
4132d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4133d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cu_start_offset = get_position_of_Cursor( &info );
4134d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         TRACE_D3("\n");
4135d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         TRACE_D3("  Compilation Unit @ offset 0x%lx:\n", cu_start_offset);
4136746e97e7098def65d59c79d5d661f9a757a837cdphilippe         /* parse_CU_header initialises the CU's abbv hash table.  */
41375d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         parse_CU_Header( &cc, td3, &info, escn_debug_abbv, True, False );
4138d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4139d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* Needed by cook_die.  */
41405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.types_cuOff_bias = escn_debug_info.szB;
4141d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4142d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         record_signatured_type( signature_types, cc.type_signature,
4143d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                                 cook_die( &cc, cc.type_offset ));
4144d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4145d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* Until proven otherwise we assume we don't need the icc9
4146d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            workaround in this case; see the DIE-reading loop below
4147d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            for details.  */
4148d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cu_offset_now = (cu_start_offset + cc.unit_length
4149d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                          + (cc.is_dw64 ? 12 : 4));
4150d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4151746e97e7098def65d59c79d5d661f9a757a837cdphilippe         if (cu_offset_now >= escn_debug_types.szB) {
4152746e97e7098def65d59c79d5d661f9a757a837cdphilippe            clear_CUConst ( &cc);
4153d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            break;
4154746e97e7098def65d59c79d5d661f9a757a837cdphilippe         }
4155d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4156d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         set_position_of_Cursor ( &info, cu_offset_now );
4157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4158d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   }
4159d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4160f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   /* Perform three DIE-reading passes.  The first pass reads DIEs from
4161f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      alternate .debug_info (if any), the second pass reads DIEs from
4162f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      .debug_info, and the third pass reads DIEs from .debug_types.
4163d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      Moving the body of this loop into a separate function would
4164d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      require a large number of arguments to be passed in, so it is
4165d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      kept inline instead.  */
4166f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   for (pass = 0; pass < 3; ++pass) {
41675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      ULong section_size;
4168d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4169d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      if (pass == 0) {
41705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (!ML_(sli_is_valid)(escn_debug_info_alt))
4171f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj	    continue;
4172f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         /* Now loop over the Compilation Units listed in the alternate
4173f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            .debug_info section (see D3SPEC sec 7.5) paras 1 and 2.
4174f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            Each compilation unit contains a Compilation Unit Header
4175f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            followed by precisely one DW_TAG_compile_unit or
4176f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            DW_TAG_partial_unit DIE. */
41775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         init_Cursor( &info, escn_debug_info_alt, 0, barf,
4178f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                      "Overrun whilst reading alternate .debug_info section" );
41795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         section_size = escn_debug_info_alt.szB;
4180f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj
4181f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         TRACE_D3("\n------ Parsing alternate .debug_info section ------\n");
4182f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      } else if (pass == 1) {
4183d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* Now loop over the Compilation Units listed in the .debug_info
4184d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            section (see D3SPEC sec 7.5) paras 1 and 2.  Each compilation
4185d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            unit contains a Compilation Unit Header followed by precisely
4186d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            one DW_TAG_compile_unit or DW_TAG_partial_unit DIE. */
41875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         init_Cursor( &info, escn_debug_info, 0, barf,
4188d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                      "Overrun whilst reading .debug_info section" );
41895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         section_size = escn_debug_info.szB;
4190d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4191d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         TRACE_D3("\n------ Parsing .debug_info section ------\n");
4192d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      } else {
41935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (!ML_(sli_is_valid)(escn_debug_types))
4194d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            continue;
4195e504887521dfee904f4dcea3655515bc99a6801fphilippe         if (!VG_(clo_read_var_info))
4196e504887521dfee904f4dcea3655515bc99a6801fphilippe            continue; // Types not needed when only reading inline info.
41975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         init_Cursor( &info, escn_debug_types, 0, barf,
4198d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                      "Overrun whilst reading .debug_types section" );
41995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         section_size = escn_debug_types.szB;
4200d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4201d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         TRACE_D3("\n------ Parsing .debug_types section ------\n");
4202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4204d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      while (True) {
42055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong   cu_start_offset, cu_offset_now;
4206d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         CUConst cc;
4207d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* It may be that the stated size of this CU is larger than the
4208d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            amount of stuff actually in it.  icc9 seems to generate CUs
4209d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            thusly.  We use these variables to figure out if this is
4210d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            indeed the case, and if so how many bytes we need to skip to
4211d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            get to the start of the next CU.  Not skipping those bytes
4212d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            causes us to misidentify the start of the next CU, and it all
4213d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            goes badly wrong after that (not surprisingly). */
4214d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         UWord cu_size_including_IniLen, cu_amount_used;
4215d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4216d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* It seems icc9 finishes the DIE info before debug_info_sz
4217d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            bytes have been used up.  So be flexible, and declare the
4218d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            sequence complete if there is not enough remaining bytes to
4219d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            hold even the smallest conceivable CU header.  (11 bytes I
4220d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            reckon). */
4221d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* JRS 23Jan09: I suspect this is no longer necessary now that
4222d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            the code below contains a 'while (cu_amount_used <
4223d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            cu_size_including_IniLen ...'  style loop, which skips over
4224d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            any leftover bytes at the end of a CU in the case where the
4225d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            CU's stated size is larger than its actual size (as
4226d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            determined by reading all its DIEs).  However, for prudence,
4227d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            I'll leave the following test in place.  I can't see that a
4228d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            CU header can be smaller than 11 bytes, so I don't think
4229d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            there's any harm possible through the test -- it just adds
4230d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            robustness. */
4231d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         Word avail = get_remaining_length_Cursor( &info );
4232d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         if (avail < 11) {
4233d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            if (avail > 0)
4234d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj               TRACE_D3("new_dwarf3_reader_wrk: warning: "
4235d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                        "%ld unused bytes after end of DIEs\n", avail);
4236d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            break;
4237d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         }
4238d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4239a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (VG_(clo_read_var_info)) {
4240a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            /* Check the varparser's stack is in a sane state. */
4241a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            vg_assert(varparser.sp == -1);
4242a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            for (i = 0; i < N_D3_VAR_STACK; i++) {
4243a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               vg_assert(varparser.ranges[i] == NULL);
4244a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               vg_assert(varparser.level[i] == 0);
4245a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            }
4246a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            for (i = 0; i < N_D3_TYPE_STACK; i++) {
4247a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               vg_assert(typarser.qparentE[i].cuOff == D3_INVALID_CUOFF);
4248a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               vg_assert(typarser.qparentE[i].tag   == Te_EMPTY);
4249a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               vg_assert(typarser.qlevel[i] == 0);
4250a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            }
4251d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         }
4252d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4253d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cu_start_offset = get_position_of_Cursor( &info );
4254d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         TRACE_D3("\n");
42555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("  Compilation Unit @ offset 0x%llx:\n", cu_start_offset);
42560d2ea9d1cfd6f1fff0992096c2d15881becfe2e1philippe         /* parse_CU_header initialises the CU's hashtable of abbvs ht_abbvs */
42575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (pass == 0) {
42585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            parse_CU_Header( &cc, td3, &info, escn_debug_abbv_alt,
4259f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                             False, True );
42605d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         } else {
42615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            parse_CU_Header( &cc, td3, &info, escn_debug_abbv,
4262f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                             pass == 2, False );
42635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
42645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_str      = pass == 0 ? escn_debug_str_alt
42655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                            : escn_debug_str;
42665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_ranges   = escn_debug_ranges;
42675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_loc      = escn_debug_loc;
42685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_line     = pass == 0 ? escn_debug_line_alt
42695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                            : escn_debug_line;
42705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_info     = pass == 0 ? escn_debug_info_alt
42715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                            : escn_debug_info;
42725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_types    = escn_debug_types;
42735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_info_alt = escn_debug_info_alt;
42745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_str_alt  = escn_debug_str_alt;
42755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.types_cuOff_bias    = escn_debug_info.szB;
42765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.alt_cuOff_bias      = escn_debug_info.szB + escn_debug_types.szB;
42775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.cu_start_offset     = cu_start_offset;
4278d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cc.di = di;
4279d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* The CU's svma can be deduced by looking at the AT_low_pc
4280d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            value in the top level TAG_compile_unit, which is the topmost
4281d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            DIE.  We'll leave it for the 'varparser' to acquire that info
4282d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            and fill it in -- since it is the only party to want to know
4283d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            it. */
4284d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cc.cu_svma_known = False;
4285d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cc.cu_svma       = 0;
4286d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4287a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (VG_(clo_read_var_info)) {
4288a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            cc.signature_types = signature_types;
4289a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4290a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            /* Create a fake outermost-level range covering the entire
4291a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               address range.  So we always have *something* to catch all
4292a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               variable declarations. */
4293a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            varstack_push( &cc, &varparser, td3,
4294a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                           unitary_range_list(0UL, ~0UL),
4295a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                           -1, False/*isFunc*/, NULL/*fbGX*/ );
4296a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4297a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            /* And set up the file name table.  When we come across the top
4298a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               level DIE for this CU (which is what the next call to
4299a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               read_DIE should process) we will copy all the file names out
4300a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               of the .debug_line img area and use this table to look up the
4301a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               copies when we later see filename numbers in DW_TAG_variables
4302a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               etc. */
4303a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            vg_assert(!varparser.filenameTable );
4304a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            varparser.filenameTable
4305a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.5var",
4306a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             ML_(dinfo_free),
4307a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             sizeof(UChar*) );
4308a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            vg_assert(varparser.filenameTable);
4309a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
4310a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4311a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (VG_(clo_read_inline_info)) {
4312a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            /* filename table for the inlined call parser */
4313a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            vg_assert(!inlparser.filenameTable );
4314a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            inlparser.filenameTable
4315a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.5inl",
4316a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             ML_(dinfo_free),
4317a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             sizeof(UChar*) );
4318a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            vg_assert(inlparser.filenameTable);
4319a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
4320d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4321d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* Now read the one-and-only top-level DIE for this CU. */
4322a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         vg_assert(!VG_(clo_read_var_info) || varparser.sp == 0);
4323d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         read_DIE( rangestree,
4324d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                   tyents, tempvars, gexprs,
4325a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                   &typarser, &varparser, &inlparser,
4326d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                   &info, td3, &cc, 0 );
4327d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4328055b0f85aaa42477a803d445885c389561d3d3c8sewardj         cu_offset_now = get_position_of_Cursor( &info );
4329055b0f85aaa42477a803d445885c389561d3d3c8sewardj
43305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (0) VG_(printf)("Travelled: %llu  size %llu\n",
4331d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                            cu_offset_now - cc.cu_start_offset,
4332d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                            cc.unit_length + (cc.is_dw64 ? 12 : 4));
43334bad5933e7b59ab9c756fb71da0f7fea7c4e61f0philippe
4334d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* How big the CU claims it is .. */
4335d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cu_size_including_IniLen = cc.unit_length + (cc.is_dw64 ? 12 : 4);
4336d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* .. vs how big we have found it to be */
4337d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cu_amount_used = cu_offset_now - cc.cu_start_offset;
4338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
43395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (1) TRACE_D3("offset now %lld, d-i-size %lld\n",
4340d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                         cu_offset_now, section_size);
4341d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         if (cu_offset_now > section_size)
4342d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            barf("toplevel DIEs beyond end of CU");
4343d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4344d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* If the CU is bigger than it claims to be, we've got a serious
4345d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            problem. */
4346d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         if (cu_amount_used > cu_size_including_IniLen)
4347d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            barf("CU's actual size appears to be larger than it claims it is");
4348d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4349d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* If the CU is smaller than it claims to be, we need to skip some
4350d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            bytes.  Loop updates cu_offset_new and cu_amount_used. */
4351d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         while (cu_amount_used < cu_size_including_IniLen
4352d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                && get_remaining_length_Cursor( &info ) > 0) {
4353d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            if (0) VG_(printf)("SKIP\n");
4354d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            (void)get_UChar( &info );
4355d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            cu_offset_now = get_position_of_Cursor( &info );
4356d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            cu_amount_used = cu_offset_now - cc.cu_start_offset;
4357d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         }
4358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4359a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (VG_(clo_read_var_info)) {
4360a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            /* Preen to level -2.  DIEs have level >= 0 so -2 cannot occur
4361a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               anywhere else at all.  Our fake the-entire-address-space
4362a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               range is at level -1, so preening to -2 should completely
4363a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               empty the stack out. */
4364a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            TRACE_D3("\n");
4365a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            varstack_preen( &varparser, td3, -2 );
4366a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            /* Similarly, empty the type stack out. */
4367a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            typestack_preen( &typarser, td3, -2 );
4368a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
4369d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4370a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (VG_(clo_read_var_info)) {
4371a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            vg_assert(varparser.filenameTable );
4372a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            VG_(deleteXA)( varparser.filenameTable );
4373a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            varparser.filenameTable = NULL;
4374a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            vg_assert(inlparser.filenameTable );
4375a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
4376a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (VG_(clo_read_inline_info)) {
4377a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            VG_(deleteXA)( inlparser.filenameTable );
4378a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            inlparser.filenameTable = NULL;
4379a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
4380746e97e7098def65d59c79d5d661f9a757a837cdphilippe         clear_CUConst(&cc);
4381d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4382d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         if (cu_offset_now == section_size)
4383d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            break;
4384d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* else keep going */
4385d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      }
4386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4387b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4388b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4389a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (VG_(clo_read_var_info)) {
4390a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* From here on we're post-processing the stuff we got
4391a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         out of the .debug_info section. */
4392a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (td3) {
4393a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         TRACE_D3("\n");
4394a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ML_(pp_TyEnts)(tyents, "Initial type entity (TyEnt) array");
4395a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         TRACE_D3("\n");
4396a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         TRACE_D3("------ Compressing type entries ------\n");
4397a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
4398a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4399a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      tyents_cache = ML_(dinfo_zalloc)( "di.readdwarf3.ndrw.6",
4400a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                                        sizeof(TyEntIndexCache) );
4401a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      ML_(TyEntIndexCache__invalidate)( tyents_cache );
4402a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      dedup_types( td3, tyents, tyents_cache );
4403a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (td3) {
4404a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         TRACE_D3("\n");
4405a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ML_(pp_TyEnts)(tyents, "After type entity (TyEnt) compression");
4406a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
4407a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
44089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TRACE_D3("\n");
4409a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      TRACE_D3("------ Resolving the types of variables ------\n" );
4410a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      resolve_variable_types( barf, tyents, tyents_cache, tempvars );
44119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
4412a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Copy all the non-INDIR tyents into a new table.  For large
4413a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         .so's, about 90% of the tyents will by now have been resolved to
4414a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         INDIRs, and we no longer need them, and so don't need to store
4415a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         them. */
4416a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      tyents_to_keep
4417a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         = VG_(newXA)( ML_(dinfo_zalloc),
4418a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                       "di.readdwarf3.ndrw.7 (TyEnt to-keep array)",
4419a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                       ML_(dinfo_free), sizeof(TyEnt) );
4420a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      n = VG_(sizeXA)( tyents );
4421a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      for (i = 0; i < n; i++) {
4422a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         TyEnt* ent = VG_(indexXA)( tyents, i );
4423a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (ent->tag != Te_INDIR)
4424a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            VG_(addToXA)( tyents_to_keep, ent );
4425a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
44269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
4427a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(deleteXA)( tyents );
4428a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      tyents = NULL;
4429a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      ML_(dinfo_free)( tyents_cache );
4430a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      tyents_cache = NULL;
4431a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4432a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Sort tyents_to_keep so we can lookup in it.  A complete (if
4433a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         minor) waste of time, since tyents itself is sorted, but
4434a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         necessary since VG_(lookupXA) refuses to cooperate if we
4435a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         don't. */
4436a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(setCmpFnXA)( tyents_to_keep, (XACmpFn_t) ML_(TyEnt__cmp_by_cuOff_only) );
4437a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(sortXA)( tyents_to_keep );
4438a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4439a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Enable cacheing on tyents_to_keep */
4440a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      tyents_to_keep_cache
4441a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         = ML_(dinfo_zalloc)( "di.readdwarf3.ndrw.8",
4442a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                              sizeof(TyEntIndexCache) );
4443a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      ML_(TyEntIndexCache__invalidate)( tyents_to_keep_cache );
4444a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4445a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* And record the tyents in the DebugInfo.  We do this before
4446a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         starting to hand variables to ML_(addVar), since if ML_(addVar)
4447a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         wants to do debug printing (of the types of said vars) then it
4448a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         will need the tyents.*/
4449a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      vg_assert(!di->admin_tyents);
4450a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      di->admin_tyents = tyents_to_keep;
4451a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4452a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Bias all the location expressions. */
4453a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      TRACE_D3("\n");
4454a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      TRACE_D3("------ Biasing the location expressions ------\n" );
445568a2ebd9384661a85a4674fe8310c595ad494305sewardj
4456a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      n = VG_(sizeXA)( gexprs );
4457a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      for (i = 0; i < n; i++) {
4458a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         gexpr = *(GExpr**)VG_(indexXA)( gexprs, i );
4459a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         bias_GX( gexpr, di );
4460a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
4461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4462a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      TRACE_D3("\n");
4463a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      TRACE_D3("------ Acquired the following variables: ------\n\n");
4464a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4465a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Park (pointers to) all the vars in an XArray, so we can look up
4466a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         abstract origins quickly.  The array is sorted (hence, looked-up
4467a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         by) the .dioff fields.  Since the .dioffs should be in strictly
4468a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ascending order, there is no need to sort the array after
4469a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         construction.  The ascendingness is however asserted for. */
4470a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      dioff_lookup_tab
4471a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.9",
4472a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                       ML_(dinfo_free),
4473a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                       sizeof(TempVar*) );
4474a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      vg_assert(dioff_lookup_tab);
4475a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4476a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      n = VG_(sizeXA)( tempvars );
4477a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Word first_primary_var = 0;
4478a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      for (first_primary_var = 0;
4479a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           escn_debug_info_alt.szB/*really?*/ && first_primary_var < n;
4480a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           first_primary_var++) {
4481a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         varp = *(TempVar**)VG_(indexXA)( tempvars, first_primary_var );
4482a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (varp->dioff < escn_debug_info.szB + escn_debug_types.szB)
4483a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            break;
448459a2d18d0ddfa241850017252b0804d469187d79sewardj      }
4485a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      for (i = 0; i < n; i++) {
4486a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         varp = *(TempVar**)VG_(indexXA)( tempvars, (i + first_primary_var) % n );
4487a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (i > first_primary_var) {
4488a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            varp2 = *(TempVar**)VG_(indexXA)( tempvars,
4489a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                                              (i + first_primary_var - 1) % n );
4490a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            /* why should this hold?  Only, I think, because we've
4491a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               constructed the array by reading .debug_info sequentially,
4492a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               and so the array .dioff fields should reflect that, and be
4493a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               strictly ascending. */
4494a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            vg_assert(varp2->dioff < varp->dioff);
4495a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
4496a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         VG_(addToXA)( dioff_lookup_tab, &varp );
4497a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
4498a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(setCmpFnXA)( dioff_lookup_tab, cmp_TempVar_by_dioff );
4499a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(sortXA)( dioff_lookup_tab ); /* POINTLESS; FIXME: rm */
4500b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4501a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Now visit each var.  Collect up as much info as possible for
4502a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         each var and hand it to ML_(addVar). */
4503a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      n = VG_(sizeXA)( tempvars );
4504a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      for (j = 0; j < n; j++) {
4505a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         TyEnt* ent;
4506a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         varp = *(TempVar**)VG_(indexXA)( tempvars, j );
4507b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4508a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* Possibly show .. */
4509a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (td3) {
4510a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            VG_(printf)("<%lx> addVar: level %d: %s :: ",
4511a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        varp->dioff,
4512a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        varp->level,
4513a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        varp->name ? varp->name : "<anon_var>" );
4514a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (varp->typeR) {
4515a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               ML_(pp_TyEnt_C_ishly)( tyents_to_keep, varp->typeR );
4516a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            } else {
4517a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               VG_(printf)("NULL");
4518a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            }
4519a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            VG_(printf)("\n  Loc=");
4520a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (varp->gexpr) {
4521a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               ML_(pp_GX)(varp->gexpr);
4522a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            } else {
4523a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               VG_(printf)("NULL");
4524a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            }
4525b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            VG_(printf)("\n");
4526a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (varp->fbGX) {
4527a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               VG_(printf)("  FrB=");
4528a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               ML_(pp_GX)( varp->fbGX );
4529a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               VG_(printf)("\n");
4530a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            } else {
4531a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               VG_(printf)("  FrB=none\n");
4532a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            }
4533a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            VG_(printf)("  declared at: %s:%d\n",
4534a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        varp->fName ? varp->fName : "NULL",
4535a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        varp->fLine );
4536a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (varp->absOri != (UWord)D3_INVALID_CUOFF)
4537a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               VG_(printf)("  abstract origin: <%lx>\n", varp->absOri);
4538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
4539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4540a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* Skip variables which have no location.  These must be
4541a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            abstract instances; they are useless as-is since with no
4542a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            location they have no specified memory location.  They will
4543a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            presumably be referred to via the absOri fields of other
4544a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            variables. */
4545a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (!varp->gexpr) {
4546a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            TRACE_D3("  SKIP (no location)\n\n");
4547bdee918842b4b2d4a09146a4642e999dc71b3652sewardj            continue;
4548bdee918842b4b2d4a09146a4642e999dc71b3652sewardj         }
4549b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4550a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* So it has a location, at least.  If it refers to some other
4551a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            entry through its absOri field, pull in further info through
4552a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            that. */
4553a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (varp->absOri != (UWord)D3_INVALID_CUOFF) {
4554a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            Bool found;
4555a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            Word ixFirst, ixLast;
4556a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            TempVar key;
4557a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            TempVar* keyp = &key;
4558a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            TempVar *varAI;
4559a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            VG_(memset)(&key, 0, sizeof(key)); /* not necessary */
4560a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            key.dioff = varp->absOri; /* this is what we want to find */
4561a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            found = VG_(lookupXA)( dioff_lookup_tab, &keyp,
4562a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                                   &ixFirst, &ixLast );
4563a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (!found) {
4564a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               /* barf("DW_AT_abstract_origin can't be resolved"); */
4565a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               TRACE_D3("  SKIP (DW_AT_abstract_origin can't be resolved)\n\n");
4566a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               continue;
4567a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            }
4568a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            /* If the following fails, there is more than one entry with
4569a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               the same dioff.  Which can't happen. */
4570a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            vg_assert(ixFirst == ixLast);
4571a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            varAI = *(TempVar**)VG_(indexXA)( dioff_lookup_tab, ixFirst );
4572a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            /* stay sane */
4573a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            vg_assert(varAI);
4574a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            vg_assert(varAI->dioff == varp->absOri);
4575a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4576a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            /* Copy what useful info we can. */
4577a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (varAI->typeR && !varp->typeR)
4578a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               varp->typeR = varAI->typeR;
4579a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (varAI->name && !varp->name)
4580a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               varp->name = varAI->name;
4581a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (varAI->fName && !varp->fName)
4582a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               varp->fName = varAI->fName;
4583a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (varAI->fLine > 0 && varp->fLine == 0)
4584a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               varp->fLine = varAI->fLine;
4585a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
4586a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4587a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* Give it a name if it doesn't have one. */
4588a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (!varp->name)
4589a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            varp->name = ML_(addStr)( di, "<anon_var>", -1 );
4590a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4591a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* So now does it have enough info to be useful? */
4592a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* NOTE: re typeR: this is a hack.  If typeR is Te_UNKNOWN then
4593a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            the type didn't get resolved.  Really, in that case
4594a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            something's broken earlier on, and should be fixed, rather
4595a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            than just skipping the variable. */
4596a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ent = ML_(TyEnts__index_by_cuOff)( tyents_to_keep,
4597a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                                            tyents_to_keep_cache,
4598a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                                            varp->typeR );
4599a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* The next two assertions should be guaranteed by
4600a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            our previous call to resolve_variable_types. */
4601a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         vg_assert(ent);
4602a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         vg_assert(ML_(TyEnt__is_type)(ent) || ent->tag == Te_UNKNOWN);
4603a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4604a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (ent->tag == Te_UNKNOWN) continue;
4605a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4606a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         vg_assert(varp->gexpr);
4607a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         vg_assert(varp->name);
4608a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         vg_assert(varp->typeR);
4609a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         vg_assert(varp->level >= 0);
4610a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4611a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* Ok.  So we're going to keep it.  Call ML_(addVar) once for
4612a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            each address range in which the variable exists. */
4613a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         TRACE_D3("  ACQUIRE for range(s) ");
4614a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         { AddrRange  oneRange;
4615a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           AddrRange* varPcRanges;
4616a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           Word       nVarPcRanges;
4617a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           /* Set up to iterate over address ranges, however
4618a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              represented. */
4619a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           if (varp->nRanges == 0 || varp->nRanges == 1) {
4620a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              vg_assert(!varp->rngMany);
4621a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              if (varp->nRanges == 0) {
4622a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 vg_assert(varp->rngOneMin == 0);
4623a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 vg_assert(varp->rngOneMax == 0);
4624a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              }
4625a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              nVarPcRanges = varp->nRanges;
4626a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              oneRange.aMin = varp->rngOneMin;
4627a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              oneRange.aMax = varp->rngOneMax;
4628a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              varPcRanges = &oneRange;
4629a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           } else {
4630a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              vg_assert(varp->rngMany);
4631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              vg_assert(varp->rngOneMin == 0);
4632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              vg_assert(varp->rngOneMax == 0);
4633a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              nVarPcRanges = VG_(sizeXA)(varp->rngMany);
4634a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              vg_assert(nVarPcRanges >= 2);
4635a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              vg_assert(nVarPcRanges == (Word)varp->nRanges);
4636a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              varPcRanges = VG_(indexXA)(varp->rngMany, 0);
4637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           }
4638a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           if (varp->level == 0)
4639a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              vg_assert( nVarPcRanges == 1 );
4640a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           /* and iterate */
4641a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           for (i = 0; i < nVarPcRanges; i++) {
4642a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              Addr pcMin = varPcRanges[i].aMin;
4643a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              Addr pcMax = varPcRanges[i].aMax;
4644a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              vg_assert(pcMin <= pcMax);
4645a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              /* Level 0 is the global address range.  So at level 0 we
4646a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 don't want to bias pcMin/pcMax; but at all other levels
4647a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 we do since those are derived from svmas in the Dwarf
4648a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 we're reading.  Be paranoid ... */
4649a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              if (varp->level == 0) {
4650a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 vg_assert(pcMin == (Addr)0);
4651a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 vg_assert(pcMax == ~(Addr)0);
4652a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              } else {
4653a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 /* vg_assert(pcMin > (Addr)0);
4654a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                    No .. we can legitimately expect to see ranges like
4655a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                    0x0-0x11D (pre-biasing, of course). */
4656a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 vg_assert(pcMax < ~(Addr)0);
4657a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              }
4658a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4659a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              /* Apply text biasing, for non-global variables. */
4660a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              if (varp->level > 0) {
4661a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 pcMin += di->text_debug_bias;
4662a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 pcMax += di->text_debug_bias;
4663a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              }
4664a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4665a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              if (i > 0 && (i%2) == 0)
4666a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 TRACE_D3("\n                       ");
4667a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              TRACE_D3("[%#lx,%#lx] ", pcMin, pcMax );
4668a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4669a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              ML_(addVar)(
4670a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 di, varp->level,
4671a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     pcMin, pcMax,
4672a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     varp->name,  varp->typeR,
4673a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     varp->gexpr, varp->fbGX,
4674a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     varp->fName, varp->fLine, td3
4675a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              );
4676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           }
4677a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
4678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4679a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         TRACE_D3("\n\n");
4680a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* and move on to the next var */
4681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4683a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Now free all the TempVars */
4684a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      n = VG_(sizeXA)( tempvars );
4685a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      for (i = 0; i < n; i++) {
4686a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         varp = *(TempVar**)VG_(indexXA)( tempvars, i );
4687a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ML_(dinfo_free)(varp);
4688a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
4689a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(deleteXA)( tempvars );
4690a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      tempvars = NULL;
4691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4692a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* and the temp lookup table */
4693a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(deleteXA)( dioff_lookup_tab );
4694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4695a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* and the ranges tree.  Note that we need to also free the XArrays
4696a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         which constitute the keys, hence pass VG_(deleteXA) as a
4697a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         key-finalizer. */
4698a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(deleteFM)( rangestree, (void(*)(UWord))VG_(deleteXA), NULL );
46999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
4700a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* and the tyents_to_keep cache */
4701a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      ML_(dinfo_free)( tyents_to_keep_cache );
4702a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      tyents_to_keep_cache = NULL;
47039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
4704a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      vg_assert( varparser.filenameTable == NULL );
4705d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4706a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* And the signatured type hash.  */
4707a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(HT_destruct) ( signature_types, ML_(dinfo_free) );
47089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
4709a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* record the GExprs in di so they can be freed later */
4710a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      vg_assert(!di->admin_gexprs);
4711a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      di->admin_gexprs = gexprs;
4712a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
4713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
4717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
4718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- The "new" DWARF3 reader -- top level control logic   ---*/
4719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
4720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
4721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
47226c591e15c1d6402a2a755310f005f795b68e7e38sewardjstatic Bool               d3rd_jmpbuf_valid  = False;
47236bd9dc18c043927c1196caba20a327238a179c42florianstatic const HChar*       d3rd_jmpbuf_reason = NULL;
472497d3ebba515c00930db4ee3f52af571bc84b2ef6sewardjstatic VG_MINIMAL_JMP_BUF(d3rd_jmpbuf);
4725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
47266bd9dc18c043927c1196caba20a327238a179c42florianstatic __attribute__((noreturn)) void barf ( const HChar* reason ) {
4727b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(d3rd_jmpbuf_valid);
4728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   d3rd_jmpbuf_reason = reason;
47296c591e15c1d6402a2a755310f005f795b68e7e38sewardj   VG_MINIMAL_LONGJMP(d3rd_jmpbuf);
4730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
4731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(0);
4732b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid
4736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjML_(new_dwarf3_reader) (
4737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct _DebugInfo* di,
47385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_info,      DiSlice escn_debug_types,
47395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_abbv,      DiSlice escn_debug_line,
47405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_str,       DiSlice escn_debug_ranges,
47415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_loc,       DiSlice escn_debug_info_alt,
47425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_abbv_alt,  DiSlice escn_debug_line_alt,
47435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_str_alt
4744b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj)
4745b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4746b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   volatile Int  jumped;
4747b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   volatile Bool td3 = di->trace_symtab;
4748b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4749b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Run the _wrk function to read the dwarf3.  If it succeeds, it
4750b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      just returns normally.  If there is any failure, it longjmp's
4751b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      back here, having first set d3rd_jmpbuf_reason to something
4752b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      useful. */
4753b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(d3rd_jmpbuf_valid  == False);
4754b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(d3rd_jmpbuf_reason == NULL);
4755b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4756b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   d3rd_jmpbuf_valid = True;
47576c591e15c1d6402a2a755310f005f795b68e7e38sewardj   jumped = VG_MINIMAL_SETJMP(d3rd_jmpbuf);
4758b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (jumped == 0) {
4759b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* try this ... */
4760b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      new_dwarf3_reader_wrk( di, barf,
47615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             escn_debug_info,     escn_debug_types,
47625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             escn_debug_abbv,     escn_debug_line,
47635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             escn_debug_str,      escn_debug_ranges,
47645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             escn_debug_loc,      escn_debug_info_alt,
47655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             escn_debug_abbv_alt, escn_debug_line_alt,
47665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             escn_debug_str_alt );
4767b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      d3rd_jmpbuf_valid = False;
4768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("\n------ .debug_info reading was successful ------\n");
4769b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } else {
4770b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* It longjmp'd. */
4771b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      d3rd_jmpbuf_valid = False;
4772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Can't longjump without giving some sort of reason. */
4773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(d3rd_jmpbuf_reason != NULL);
4774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("\n------ .debug_info reading failed ------\n");
4776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4777b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ML_(symerr)(di, True, d3rd_jmpbuf_reason);
4778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   d3rd_jmpbuf_valid  = False;
4781b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   d3rd_jmpbuf_reason = NULL;
4782b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4783b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4784b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4785b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4786b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* --- Unused code fragments which might be useful one day. --- */
4787b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#if 0
4789b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Read the arange tables */
4790b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n");
4791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n------ The contents of .debug_arange ------\n");
4792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   init_Cursor( &aranges, debug_aranges_img,
4793b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                debug_aranges_sz, 0, barf,
4794b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                "Overrun whilst reading .debug_aranges section" );
4795b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
4796b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ULong  len, d_i_offset;
4797b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   is64;
4798b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UShort version;
4799b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar  asize, segsize;
4800b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4801b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (is_at_end_Cursor( &aranges ))
4802b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
4803b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Read one arange thingy */
4804b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* initial_length field */
4805b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      len = get_Initial_Length( &is64, &aranges,
4806b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               "in .debug_aranges: invalid initial-length field" );
4807b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      version    = get_UShort( &aranges );
4808b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      d_i_offset = get_Dwarfish_UWord( &aranges, is64 );
4809b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      asize      = get_UChar( &aranges );
4810b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      segsize    = get_UChar( &aranges );
4811b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("  Length:                   %llu\n", len);
4812b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("  Version:                  %d\n", (Int)version);
4813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("  Offset into .debug_info:  %llx\n", d_i_offset);
4814b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("  Pointer Size:             %d\n", (Int)asize);
4815b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("  Segment Size:             %d\n", (Int)segsize);
4816b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("\n");
4817b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("    Address            Length\n");
4818b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4819b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while ((get_position_of_Cursor( &aranges ) % (2 * asize)) > 0) {
4820b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (void)get_UChar( & aranges );
4821b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
4823b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ULong address = get_Dwarfish_UWord( &aranges, asize==8 );
4824b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ULong length = get_Dwarfish_UWord( &aranges, asize==8 );
4825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("    0x%016llx 0x%llx\n", address, length);
4826b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (address == 0 && length == 0) break;
4827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4828b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4829b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n");
4830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
4831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
48328b68b64759254d514d98328c496cbd88cde4c9a5njn#endif // defined(VGO_linux) || defined(VGO_darwin)
4833f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
4834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------------*/
48358b68b64759254d514d98328c496cbd88cde4c9a5njn/*--- end                                                          ---*/
4836b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------------*/
4837