readdwarf3.c revision 3e49e4c2cb9a4394fd12780618e50d19d3c3a404
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); }
165e0bd5910153720d5d15697db8063d0d4caa59d8fphilippe#define TD3 (UNLIKELY(td3))
166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj#define D3_INVALID_CUOFF  ((UWord)(-1UL))
1689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj#define D3_FAKEVOID_CUOFF ((UWord)(-2UL))
169b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct {
1725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice sli;      // to which this cursor applies
1735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiOffT  sli_next; // offset in underlying DiImage; must be >= sli.ioff
1746bd9dc18c043927c1196caba20a327238a179c42florian      void (*barf)( const HChar* ) __attribute__((noreturn));
1756bd9dc18c043927c1196caba20a327238a179c42florian      const HChar* barfstr;
176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Cursor;
178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic inline Bool is_sane_Cursor ( Cursor* c ) {
180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (!c)                return False;
181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (!c->barf)          return False;
182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (!c->barfstr)       return False;
1835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (!ML_(sli_is_valid)(c->sli))    return False;
1845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (c->sli.ioff == DiOffT_INVALID) return False;
1855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (c->sli_next < c->sli.ioff)     return False;
186b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return True;
187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj// Initialise a cursor from a DiSlice (ELF section, really) so as to
1905d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj// start reading at offset |sli_initial_offset| from the start of the
1915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj// slice.
1925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic void init_Cursor ( /*OUT*/Cursor* c,
1935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                          DiSlice sli,
1945d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                          ULong   sli_initial_offset,
1955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                          __attribute__((noreturn)) void (*barf)(const HChar*),
1966bd9dc18c043927c1196caba20a327238a179c42florian                          const HChar* barfstr )
197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(c);
1995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   VG_(bzero_inline)(c, sizeof(*c));
2005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli              = sli;
2015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next         = c->sli.ioff + sli_initial_offset;
202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   c->barf             = barf;
203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   c->barfstr          = barfstr;
204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool is_at_end_Cursor ( Cursor* c ) {
208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
2095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return c->sli_next >= c->sli.ioff + c->sli.szB;
210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline ULong get_position_of_Cursor ( Cursor* c ) {
213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
2145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return c->sli_next - c->sli.ioff;
215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic inline void set_position_of_Cursor ( Cursor* c, ULong pos ) {
2175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next = c->sli.ioff + pos;
218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
220e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippestatic inline void advance_position_of_Cursor ( Cursor* c, ULong delta ) {
221e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   c->sli_next += delta;
222e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   vg_assert(is_sane_Cursor(c));
223e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe}
224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2255d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic /*signed*/Long get_remaining_length_Cursor ( Cursor* c ) {
226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
2275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return c->sli.ioff + c->sli.szB - c->sli_next;
228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj//static void* get_address_of_Cursor ( Cursor* c ) {
2315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj//   vg_assert(is_sane_Cursor(c));
2325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj//   return &c->region_start_img[ c->region_next ];
2335d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj//}
2345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
2355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic DiCursor get_DiCursor_from_Cursor ( Cursor* c ) {
2365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return mk_DiCursor(c->sli.img, c->sli_next);
237b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* FIXME: document assumptions on endianness for
240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   get_UShort/UInt/ULong. */
241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic inline UChar get_UChar ( Cursor* c ) {
242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar r;
2435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   vg_assert(is_sane_Cursor(c));
2445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (c->sli_next + sizeof(UChar) > c->sli.ioff + c->sli.szB) {
245b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c->barf(c->barfstr);
246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*NOTREACHED*/
247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(0);
248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   r = ML_(img_get_UChar)(c->sli.img, c->sli_next);
2505d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next += sizeof(UChar);
251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return r;
252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic UShort get_UShort ( Cursor* c ) {
254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UShort r;
255b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
2565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (c->sli_next + sizeof(UShort) > c->sli.ioff + c->sli.szB) {
257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c->barf(c->barfstr);
258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*NOTREACHED*/
259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(0);
260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   r = ML_(img_get_UShort)(c->sli.img, c->sli_next);
2625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next += sizeof(UShort);
263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return r;
264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic UInt get_UInt ( Cursor* c ) {
266b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt r;
267b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
2685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (c->sli_next + sizeof(UInt) > c->sli.ioff + c->sli.szB) {
269b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c->barf(c->barfstr);
270b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*NOTREACHED*/
271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(0);
272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   r = ML_(img_get_UInt)(c->sli.img, c->sli_next);
2745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next += sizeof(UInt);
275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return r;
276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic ULong get_ULong ( Cursor* c ) {
278b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ULong r;
279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(is_sane_Cursor(c));
2805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (c->sli_next + sizeof(ULong) > c->sli.ioff + c->sli.szB) {
281b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c->barf(c->barfstr);
282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /*NOTREACHED*/
283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(0);
284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   r = ML_(img_get_ULong)(c->sli.img, c->sli_next);
2865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next += sizeof(ULong);
287b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return r;
288b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic ULong get_ULEB128 ( Cursor* c ) {
290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ULong result;
291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int   shift;
292b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar byte;
293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* unroll first iteration */
294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   byte = get_UChar( c );
295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   result = (ULong)(byte & 0x7f);
296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (LIKELY(!(byte & 0x80))) return result;
297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   shift = 7;
298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* end unroll first iteration */
299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   do {
300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      byte = get_UChar( c );
301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      result |= ((ULong)(byte & 0x7f)) << shift;
302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      shift += 7;
303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } while (byte & 0x80);
304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return result;
305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Long get_SLEB128 ( Cursor* c ) {
307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ULong  result = 0;
308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Int    shift = 0;
309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar  byte;
310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   do {
311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      byte = get_UChar(c);
312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      result |= ((ULong)(byte & 0x7f)) << shift;
313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      shift += 7;
314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } while (byte & 0x80);
315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (shift < 64 && (byte & 0x40))
316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      result |= -(1ULL << shift);
317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return result;
318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Assume 'c' points to the start of a string.  Return a DiCursor of
3215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   whatever it points at, and advance it past the terminating zero.
3225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   This makes it safe for the caller to then copy the string with
3235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   ML_(addStr), since (w.r.t. image overruns) the process of advancing
3245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   past the terminating zero will already have "vetted" the string. */
3255d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic DiCursor get_AsciiZ ( Cursor* c ) {
3265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UChar uc;
3275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiCursor res = get_DiCursor_from_Cursor(c);
328b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   do { uc = get_UChar(c); } while (uc != 0);
329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return res;
330b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic ULong peek_ULEB128 ( Cursor* c ) {
3335d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiOffT here = c->sli_next;
3345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   ULong  r    = get_ULEB128( c );
3355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next = here;
336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return r;
337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic UChar peek_UChar ( Cursor* c ) {
3395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiOffT here = c->sli_next;
3405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UChar  r    = get_UChar( c );
3415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   c->sli_next = here;
342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return r;
343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic ULong get_Dwarfish_UWord ( Cursor* c, Bool is_dw64 ) {
346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return is_dw64 ? get_ULong(c) : (ULong) get_UInt(c);
347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic UWord get_UWord ( Cursor* c ) {
350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(sizeof(UWord) == sizeof(void*));
351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (sizeof(UWord) == 4) return get_UInt(c);
352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (sizeof(UWord) == 8) return get_ULong(c);
353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(0);
354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
355b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
356b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Read a DWARF3 'Initial Length' field */
357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic ULong get_Initial_Length ( /*OUT*/Bool* is64,
358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                  Cursor* c,
3596bd9dc18c043927c1196caba20a327238a179c42florian                                  const HChar* barfMsg )
360b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ULong w64;
362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt  w32;
363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   *is64 = False;
364b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   w32 = get_UInt( c );
365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (w32 >= 0xFFFFFFF0 && w32 < 0xFFFFFFFF) {
366b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      c->barf( barfMsg );
367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   else if (w32 == 0xFFFFFFFF) {
369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      *is64 = True;
370b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      w64   = get_ULong( c );
371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } else {
372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      *is64 = False;
373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      w64 = (ULong)w32;
374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return w64;
376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- "CUConst" structure                                  ---*/
382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
385746e97e7098def65d59c79d5d661f9a757a837cdphilippetypedef
386746e97e7098def65d59c79d5d661f9a757a837cdphilippe   struct _name_form {
387e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      ULong at_name;  // Dwarf Attribute name
388e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      ULong at_form;  // Dward Attribute form
389e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      UInt  skip_szB; // Nr of bytes skippable from here ...
390e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      UInt  next_nf;  // ... to reach this attr/form index in the g_abbv.nf
391746e97e7098def65d59c79d5d661f9a757a837cdphilippe   } name_form;
392e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe/* skip_szB and n_nf are used to optimise the skipping of uninteresting DIEs.
393e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   Each name_form maintains how many (fixed) nr of bytes can be skipped from
394e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   the beginning of this form till the next attr/form to look at.
395e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   The next form to look can be:
396e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe       an 'interesting' attr/form to read while skipping a DIE
397e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe          (currently, this is only DW_AT_sibling)
398e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   or
399e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe       a variable length form which must be read to be skipped.
400e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   For a variable length form, the skip_szB will be equal to VARSZ_FORM.
401e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe
402e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   Note: this technique could also be used to speed up the parsing
403e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   of DIEs : for each parser kind, we could have the nr of bytes
404e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   to skip to directly reach the interesting form(s) for the parser. */
405746e97e7098def65d59c79d5d661f9a757a837cdphilippe
406746e97e7098def65d59c79d5d661f9a757a837cdphilippetypedef
407746e97e7098def65d59c79d5d661f9a757a837cdphilippe   struct _g_abbv {
408746e97e7098def65d59c79d5d661f9a757a837cdphilippe      struct _g_abbv *next; // read/write by hash table.
409746e97e7098def65d59c79d5d661f9a757a837cdphilippe      UWord  abbv_code;     // key, read by hash table
410746e97e7098def65d59c79d5d661f9a757a837cdphilippe      ULong  atag;
411746e97e7098def65d59c79d5d661f9a757a837cdphilippe      ULong  has_children;
412746e97e7098def65d59c79d5d661f9a757a837cdphilippe      name_form nf[0];
413746e97e7098def65d59c79d5d661f9a757a837cdphilippe      /* Variable-length array of name/form pairs, terminated
414e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         by a 0/0 pair.
415e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         The skip_szB/next_nf allows to skip efficiently a DIE
416e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         described by this g_abbv; */
417746e97e7098def65d59c79d5d661f9a757a837cdphilippe    } g_abbv;
418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Holds information that is constant through the parsing of a
420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Compilation Unit.  This is basically plumbed through to
421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   everywhere. */
422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct {
424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Call here if anything goes wrong */
4256bd9dc18c043927c1196caba20a327238a179c42florian      void (*barf)( const HChar* ) __attribute__((noreturn));
426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Is this 64-bit DWARF ? */
427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   is_dw64;
428fba428cd266b8a39db641c5fd9523daa8939bed0tom      /* Which DWARF version ?  (2, 3 or 4) */
429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UShort version;
430055b0f85aaa42477a803d445885c389561d3d3c8sewardj      /* Length of this Compilation Unit, as stated in the
431055b0f85aaa42477a803d445885c389561d3d3c8sewardj         .unit_length :: InitialLength field of the CU Header.
432055b0f85aaa42477a803d445885c389561d3d3c8sewardj         However, this size (as specified by the D3 spec) does not
433055b0f85aaa42477a803d445885c389561d3d3c8sewardj         include the size of the .unit_length field itself, which is
434055b0f85aaa42477a803d445885c389561d3d3c8sewardj         either 4 or 12 bytes (32-bit or 64-bit Dwarf3).  That value
435055b0f85aaa42477a803d445885c389561d3d3c8sewardj         can be obtained through the expression ".is_dw64 ? 12 : 4". */
436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ULong  unit_length;
437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Offset of start of this unit in .debug_info */
438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord  cu_start_offset;
439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* SVMA for this CU.  In the D3 spec, is known as the "base
440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         address of the compilation unit (last para sec 3.1.1).
441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Needed for (amongst things) interpretation of location-list
442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         values. */
443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr   cu_svma;
444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   cu_svma_known;
4455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* The debug_abbreviations table to be used for this Unit */
4475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      //UChar* debug_abbv;
448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Upper bound on size thereof (an overestimate, in general) */
4495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      //UWord  debug_abbv_maxszB;
4505d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      /* A bounded area of the image, to be used as the
4515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         debug_abbreviations table tobe used for this Unit. */
4525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice debug_abbv;
4535d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
4545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      /* Image information for various sections. */
4555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_str;
4565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_ranges;
4575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_loc;
4585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_line;
4595d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_info;
4605d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_types;
4615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_info_alt;
4625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiSlice escn_debug_str_alt;
463f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      /* How much to add to .debug_types resp. alternate .debug_info offsets
464f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         in cook_die*.  */
465f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      UWord  types_cuOff_bias;
466f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      UWord  alt_cuOff_bias;
467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* --- Needed so we can add stuff to the string table. --- */
468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      struct _DebugInfo* di;
469746e97e7098def65d59c79d5d661f9a757a837cdphilippe      /* --- a hash table of g_abbv (i.e. parsed abbreviations) --- */
470746e97e7098def65d59c79d5d661f9a757a837cdphilippe      VgHashTable ht_abbvs;
471d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
472d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      /* True if this came from .debug_types; otherwise it came from
473d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         .debug_info.  */
474d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      Bool is_type_unit;
475d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      /* For a unit coming from .debug_types, these hold the TU's type
476d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         signature and the uncooked DIE offset of the TU's signatured
477d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         type.  For a unit coming from .debug_info, these are unused.  */
478d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      ULong type_signature;
479d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      ULong type_offset;
480d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
481d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      /* Signatured type hash; computed once and then shared by all
482d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         CUs.  */
483d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      VgHashTable signature_types;
484f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj
485f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      /* True if this came from alternate .debug_info; otherwise
486f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         it came from normal .debug_info or .debug_types.  */
487f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      Bool is_alt_info;
488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   CUConst;
490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
491b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
492d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj/* Return the cooked value of DIE depending on whether CC represents a
493f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   .debug_types unit.  To cook a DIE, we pretend that the .debug_info,
494f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   .debug_types and optional alternate .debug_info sections form
495f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   a contiguous whole, so that DIEs coming from .debug_types are numbered
496f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   starting at the end of .debug_info and DIEs coming from alternate
497f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   .debug_info are numbered starting at the end of .debug_types.  */
498d935068fc7b53c8a826b3436cdfccd5b7d446903sewardjstatic UWord cook_die( CUConst* cc, UWord die )
499d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj{
500d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   if (cc->is_type_unit)
501f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      die += cc->types_cuOff_bias;
502f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   else if (cc->is_alt_info)
503f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      die += cc->alt_cuOff_bias;
504d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   return die;
505d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj}
506d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
507d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj/* Like cook_die, but understand that DIEs coming from a
508f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   DW_FORM_ref_sig8 reference are already cooked.  Also, handle
509f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   DW_FORM_GNU_ref_alt from within primary .debug_info or .debug_types
510f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   as reference to alternate .debug_info.  */
511d935068fc7b53c8a826b3436cdfccd5b7d446903sewardjstatic UWord cook_die_using_form( CUConst *cc, UWord die, DW_FORM form)
512d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj{
513d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   if (form == DW_FORM_ref_sig8)
514d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      return die;
515f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   if (form == DW_FORM_GNU_ref_alt)
516f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      return die + cc->alt_cuOff_bias;
517d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   return cook_die( cc, die );
518d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj}
519d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
520f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj/* Return the uncooked offset of DIE and set *TYPE_FLAG to true if the DIE
521f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   came from the .debug_types section and *ALT_FLAG to true if the DIE
522f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   came from alternate .debug_info section.  */
523f7c9714ea0cde18daaecb896278e85e780d3bd75sewardjstatic UWord uncook_die( CUConst *cc, UWord die, /*OUT*/Bool *type_flag,
524f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                         Bool *alt_flag )
525d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj{
526f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   *alt_flag = False;
527f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   *type_flag = False;
5285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   /* The use of escn_debug_{info,types}.szB seems safe to me even if
5295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      escn_debug_{info,types} are DiSlice_INVALID (meaning the
5305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      sections were not found), because DiSlice_INVALID.szB is always
5315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      zero.  That said, it seems unlikely we'd ever get here if
5325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      .debug_info or .debug_types were missing. */
5335d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (die >= cc->escn_debug_info.szB) {
5345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      if (die >= cc->escn_debug_info.szB + cc->escn_debug_types.szB) {
535f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         *alt_flag = True;
5365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         die -= cc->escn_debug_info.szB + cc->escn_debug_types.szB;
537f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      } else {
538f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         *type_flag = True;
5395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         die -= cc->escn_debug_info.szB;
540f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      }
541d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   }
542d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   return die;
543d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj}
544d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
546b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Helper functions for Guarded Expressions             ---*/
548b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
549b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
550b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Parse the location list starting at img-offset 'debug_loc_offset'
552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   in .debug_loc.  Results are biased with 'svma_of_referencing_CU'
553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   and so I believe are correct SVMAs for the object as a whole.  This
554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   function allocates the UChar*, and the caller must deallocate it.
555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   The resulting block is in so-called Guarded-Expression format.
556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Guarded-Expression format is similar but not identical to the DWARF3
558b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   location-list format.  The format of each returned block is:
559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar biasMe;
561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar isEnd;
562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      followed by zero or more of
563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      (Addr aMin;  Addr aMax;  UShort nbytes;  ..bytes..;  UChar isEnd)
565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   '..bytes..' is an standard DWARF3 location expression which is
567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   valid when aMin <= pc <= aMax (possibly after suitable biasing).
568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   The number of bytes in '..bytes..' is nbytes.
570b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
571b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   The end of the sequence is marked by an isEnd == 1 value.  All
572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   previous isEnd values must be zero.
573b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
574b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   biasMe is 1 if the aMin/aMax fields need this DebugInfo's
575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   text_bias added before use, and 0 if the GX is this is not
576b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   necessary (is ready to go).
577b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
578b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Hence the block can be quickly parsed and is self-describing.  Note
579b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   that aMax is 1 less than the corresponding value in a DWARF3
580b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   location list.  Zero length ranges, with aMax == aMin-1, are not
581b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   allowed.
582b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/
5839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* 2008-sept-12: moved ML_(pp_GX) from here to d3basics.c, where
5849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   it more logically belongs. */
5859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
586b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
587402c9eed11b9b60c6e134d05db938e395466cf99tom/* Apply a text bias to a GX. */
588402c9eed11b9b60c6e134d05db938e395466cf99tomstatic void bias_GX ( /*MOD*/GExpr* gx, struct _DebugInfo* di )
589b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
590b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UShort nbytes;
591b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar* p = &gx->payload[0];
59286781fabbfc019b752f9605e487cfce77b2a592atom   UChar* pA;
593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar  uc;
594b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   uc = *p++; /*biasMe*/
595b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (uc == 0)
596b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      return;
597b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(uc == 1);
598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   p[-1] = 0; /* mark it as done */
599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
600b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      uc = *p++;
601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (uc == 1)
602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break; /*isEnd*/
603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(uc == 0);
60468a2ebd9384661a85a4674fe8310c595ad494305sewardj      /* t-bias aMin */
60586781fabbfc019b752f9605e487cfce77b2a592atom      pA = (UChar*)p;
60686781fabbfc019b752f9605e487cfce77b2a592atom      ML_(write_Addr)(pA, ML_(read_Addr)(pA) + di->text_debug_bias);
60768a2ebd9384661a85a4674fe8310c595ad494305sewardj      p += sizeof(Addr);
60868a2ebd9384661a85a4674fe8310c595ad494305sewardj      /* t-bias aMax */
60986781fabbfc019b752f9605e487cfce77b2a592atom      pA = (UChar*)p;
61086781fabbfc019b752f9605e487cfce77b2a592atom      ML_(write_Addr)(pA, ML_(read_Addr)(pA) + di->text_debug_bias);
61168a2ebd9384661a85a4674fe8310c595ad494305sewardj      p += sizeof(Addr);
61268a2ebd9384661a85a4674fe8310c595ad494305sewardj      /* nbytes, and actual expression */
61386781fabbfc019b752f9605e487cfce77b2a592atom      nbytes = ML_(read_UShort)(p); p += sizeof(UShort);
614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      p += nbytes;
615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
617b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
618b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
6195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic GExpr* make_singleton_GX ( DiCursor block, ULong nbytes )
620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   SizeT  bytesReqd;
622b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   GExpr* gx;
623b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar *p, *pstart;
624b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(sizeof(UWord) == sizeof(Addr));
626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(nbytes <= 0xFFFF); /* else we overflow the nbytes field */
627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   bytesReqd
628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      =   sizeof(UChar)  /*biasMe*/    + sizeof(UChar) /*!isEnd*/
629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        + sizeof(UWord)  /*aMin*/      + sizeof(UWord) /*aMax*/
6305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj        + sizeof(UShort) /*nbytes*/    + (SizeT)nbytes
631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        + sizeof(UChar); /*isEnd*/
632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   gx = ML_(dinfo_zalloc)( "di.readdwarf3.msGX.1",
6349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                           sizeof(GExpr) + bytesReqd );
635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(gx);
636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   p = pstart = &gx->payload[0];
638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
63986781fabbfc019b752f9605e487cfce77b2a592atom   p = ML_(write_UChar)(p, 0);        /*biasMe*/
64086781fabbfc019b752f9605e487cfce77b2a592atom   p = ML_(write_UChar)(p, 0);        /*!isEnd*/
64186781fabbfc019b752f9605e487cfce77b2a592atom   p = ML_(write_Addr)(p, 0);         /*aMin*/
64286781fabbfc019b752f9605e487cfce77b2a592atom   p = ML_(write_Addr)(p, ~0);        /*aMax*/
64386781fabbfc019b752f9605e487cfce77b2a592atom   p = ML_(write_UShort)(p, nbytes);  /*nbytes*/
6445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   ML_(cur_read_get)(p, block, nbytes); p += nbytes;
64586781fabbfc019b752f9605e487cfce77b2a592atom   p = ML_(write_UChar)(p, 1);        /*isEnd*/
646b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
647b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert( (SizeT)(p - pstart) == bytesReqd);
648b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert( &gx->payload[bytesReqd]
649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              == ((UChar*)gx) + sizeof(GExpr) + bytesReqd );
650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return gx;
652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
653b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
654b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
655b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic GExpr* make_general_GX ( CUConst* cc,
656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                Bool     td3,
6575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                ULong    debug_loc_offset,
658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                Addr     svma_of_referencing_CU )
659b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Addr      base;
661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Cursor    loc;
662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   XArray*   xa; /* XArray of UChar */
663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   GExpr*    gx;
664b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Word      nbytes;
665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
666b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(sizeof(UWord) == sizeof(Addr));
6675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (!ML_(sli_is_valid)(cc->escn_debug_loc) || cc->escn_debug_loc.szB == 0)
668b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("make_general_GX: .debug_loc is empty/missing");
669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   init_Cursor( &loc, cc->escn_debug_loc, 0, cc->barf,
671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                "Overrun whilst reading .debug_loc section(2)" );
672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   set_position_of_Cursor( &loc, debug_loc_offset );
673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
6745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   TRACE_D3("make_general_GX (.debug_loc_offset = %llu, ioff = %llu) {\n",
6755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            debug_loc_offset, (ULong)get_DiCursor_from_Cursor(&loc).ioff );
676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Who frees this xa?  It is freed before this fn exits. */
6789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.mgGX.1",
6799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                    ML_(dinfo_free),
680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    sizeof(UChar) );
681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   { UChar c = 1; /*biasMe*/ VG_(addBytesToXA)( xa, &c, sizeof(c) ); }
683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   base = 0;
685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool  acquire;
687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord len;
688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Read a (host-)word pair.  This is something of a hack since
689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         the word size to read is really dictated by the ELF file;
690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         however, we assume we're reading a file with the same
691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         word-sizeness as the host.  Reasonably enough. */
692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord w1 = get_UWord( &loc );
693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord w2 = get_UWord( &loc );
694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("   %08lx %08lx\n", w1, w2);
696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 == 0 && w2 == 0)
697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break; /* end of list */
698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
699b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 == -1UL) {
700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* new value for 'base' */
701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         base = w2;
702b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         continue;
703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* else a location expression follows */
706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* else enumerate [w1+base, w2+base) */
707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* w2 is 1 past end of range, as per D3 defn for "DW_AT_high_pc"
708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (sec 2.17.2) */
709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 > w2) {
710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("negative range is for .debug_loc expr at "
7115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  "file offset %llu\n",
712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  debug_loc_offset);
713b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         cc->barf( "negative range in .debug_loc section" );
714b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
715b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
716b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* ignore zero length ranges */
717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      acquire = w1 < w2;
718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      len     = (UWord)get_UShort( &loc );
719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (acquire) {
721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UWord  w;
722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UShort s;
723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UChar  c;
724b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         c = 0; /* !isEnd*/
725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(addBytesToXA)( xa, &c, sizeof(c) );
726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         w = w1    + base + svma_of_referencing_CU;
727b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(addBytesToXA)( xa, &w, sizeof(w) );
728b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         w = w2 -1 + base + svma_of_referencing_CU;
729b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(addBytesToXA)( xa, &w, sizeof(w) );
730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         s = (UShort)len;
731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(addBytesToXA)( xa, &s, sizeof(s) );
732b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (len > 0) {
735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UChar byte = get_UChar( &loc );
736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("%02x", (UInt)byte);
737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (acquire)
738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            VG_(addBytesToXA)( xa, &byte, 1 );
739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         len--;
740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
741b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("\n");
742b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
743b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
744b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   { UChar c = 1; /*isEnd*/ VG_(addBytesToXA)( xa, &c, sizeof(c) ); }
745b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
746b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   nbytes = VG_(sizeXA)( xa );
747b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(nbytes >= 1);
748b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
7499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   gx = ML_(dinfo_zalloc)( "di.readdwarf3.mgGX.2", sizeof(GExpr) + nbytes );
750b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(gx);
751b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(memcpy)( &gx->payload[0], (UChar*)VG_(indexXA)(xa,0), nbytes );
752b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert( &gx->payload[nbytes]
753b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              == ((UChar*)gx) + sizeof(GExpr) + nbytes );
754b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
755b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(deleteXA)( xa );
756b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
757b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3("}\n");
758b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
759b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return gx;
760b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
762b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
763b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
764b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
765b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Helper functions for range lists and CU headers      ---*/
766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
767b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
769b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Denotes an address range.  Both aMin and aMax are included in the
770b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   range; hence a complete range is (0, ~0) and an empty range is any
771b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   (X, X-1) for X > 0.*/
772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct { Addr aMin; Addr aMax; }
774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   AddrRange;
775b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
776b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
7779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Generate an arbitrary structural total ordering on
7789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   XArray* of AddrRange. */
7799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic Word cmp__XArrays_of_AddrRange ( XArray* rngs1, XArray* rngs2 )
7809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
7819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Word n1, n2, i;
7829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   tl_assert(rngs1 && rngs2);
7839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   n1 = VG_(sizeXA)( rngs1 );
7849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   n2 = VG_(sizeXA)( rngs2 );
7859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (n1 < n2) return -1;
7869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (n1 > n2) return 1;
7879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   for (i = 0; i < n1; i++) {
7889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      AddrRange* rng1 = (AddrRange*)VG_(indexXA)( rngs1, i );
7899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      AddrRange* rng2 = (AddrRange*)VG_(indexXA)( rngs2, i );
7909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (rng1->aMin < rng2->aMin) return -1;
7919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (rng1->aMin > rng2->aMin) return 1;
7929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (rng1->aMax < rng2->aMax) return -1;
7939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (rng1->aMax > rng2->aMax) return 1;
7949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
7959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   return 0;
7969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj}
7979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
7989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
799b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
800b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic XArray* /* of AddrRange */ empty_range_list ( void )
801b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
802b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   XArray* xa; /* XArray of AddrRange */
803b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Who frees this xa?  varstack_preen() does. */
8049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.erl.1",
8059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                    ML_(dinfo_free),
806b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    sizeof(AddrRange) );
807b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return xa;
808b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
809b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
810b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
8119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj__attribute__((noinline))
812b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic XArray* unitary_range_list ( Addr aMin, Addr aMax )
813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
814b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   XArray*   xa;
815b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   AddrRange pair;
816b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(aMin <= aMax);
817b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Who frees this xa?  varstack_preen() does. */
8189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   xa = VG_(newXA)( ML_(dinfo_zalloc),  "di.readdwarf3.url.1",
8199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                    ML_(dinfo_free),
820b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    sizeof(AddrRange) );
821b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   pair.aMin = aMin;
822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   pair.aMax = aMax;
823b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(addToXA)( xa, &pair );
824b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return xa;
825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
826b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
828b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Enumerate the address ranges starting at img-offset
829b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   'debug_ranges_offset' in .debug_ranges.  Results are biased with
830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   'svma_of_referencing_CU' and so I believe are correct SVMAs for the
831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   object as a whole.  This function allocates the XArray, and the
832b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   caller must deallocate it. */
833b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic XArray* /* of AddrRange */
835b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj       get_range_list ( CUConst* cc,
836b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        Bool     td3,
837b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        UWord    debug_ranges_offset,
838b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        Addr     svma_of_referencing_CU )
839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
840b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Addr      base;
841b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Cursor    ranges;
842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   XArray*   xa; /* XArray of AddrRange */
843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   AddrRange pair;
844b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
8455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (!ML_(sli_is_valid)(cc->escn_debug_ranges)
8465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj       || cc->escn_debug_ranges.szB == 0)
847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("get_range_list: .debug_ranges is empty/missing");
848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
8495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   init_Cursor( &ranges, cc->escn_debug_ranges, 0, cc->barf,
850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                "Overrun whilst reading .debug_ranges section(2)" );
851b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   set_position_of_Cursor( &ranges, debug_ranges_offset );
852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Who frees this xa?  varstack_preen() does. */
8549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.grl.1", ML_(dinfo_free),
855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    sizeof(AddrRange) );
856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   base = 0;
857b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
858b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Read a (host-)word pair.  This is something of a hack since
859b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         the word size to read is really dictated by the ELF file;
860b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         however, we assume we're reading a file with the same
861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         word-sizeness as the host.  Reasonably enough. */
862b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord w1 = get_UWord( &ranges );
863b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord w2 = get_UWord( &ranges );
864b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
865b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 == 0 && w2 == 0)
866b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break; /* end of list. */
867b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
868b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 == -1UL) {
869b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* new value for 'base' */
870b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         base = w2;
871b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         continue;
872b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
873b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
874b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* else enumerate [w1+base, w2+base) */
875b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* w2 is 1 past end of range, as per D3 defn for "DW_AT_high_pc"
876b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (sec 2.17.2) */
877b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 > w2)
878b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         cc->barf( "negative range in .debug_ranges section" );
879b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (w1 < w2) {
880b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         pair.aMin = w1     + base + svma_of_referencing_CU;
881b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         pair.aMax = w2 - 1 + base + svma_of_referencing_CU;
882b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vg_assert(pair.aMin <= pair.aMax);
883b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(addToXA)( xa, &pair );
884b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
885b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
886b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return xa;
887b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
888b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
889e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe#define VARSZ_FORM 0xffffffff
890e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippestatic UInt get_Form_szB (CUConst* cc, DW_FORM form );
891e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe
892746e97e7098def65d59c79d5d661f9a757a837cdphilippe/* Initialises the hash table of abbreviations.
893746e97e7098def65d59c79d5d661f9a757a837cdphilippe   We do a single scan of the abbv slice to parse and
894746e97e7098def65d59c79d5d661f9a757a837cdphilippe   build all abbreviations, for the following reasons:
895746e97e7098def65d59c79d5d661f9a757a837cdphilippe     * all or most abbreviations will be needed in any case
896746e97e7098def65d59c79d5d661f9a757a837cdphilippe       (at least for var-info reading).
897746e97e7098def65d59c79d5d661f9a757a837cdphilippe     * re-reading each time an abbreviation causes a lot of calls
898746e97e7098def65d59c79d5d661f9a757a837cdphilippe       to get_ULEB128.
899746e97e7098def65d59c79d5d661f9a757a837cdphilippe     * a CU should not have many abbreviations. */
900746e97e7098def65d59c79d5d661f9a757a837cdphilippestatic void init_ht_abbvs (CUConst* cc,
901746e97e7098def65d59c79d5d661f9a757a837cdphilippe                           Bool td3)
902746e97e7098def65d59c79d5d661f9a757a837cdphilippe{
903746e97e7098def65d59c79d5d661f9a757a837cdphilippe   Cursor c;
904746e97e7098def65d59c79d5d661f9a757a837cdphilippe   g_abbv *ta; // temporary abbreviation, reallocated if needed.
905746e97e7098def65d59c79d5d661f9a757a837cdphilippe   UInt ta_nf_maxE; // max nr of pairs in ta.nf[], doubled when reallocated.
906746e97e7098def65d59c79d5d661f9a757a837cdphilippe   UInt ta_nf_n;    // nr of pairs in ta->nf that are initialised.
907e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   g_abbv *ht_ta; // abbv to insert in hash table.
908e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   Int i;
909746e97e7098def65d59c79d5d661f9a757a837cdphilippe
910746e97e7098def65d59c79d5d661f9a757a837cdphilippe   #define SZ_G_ABBV(_nf_szE) (sizeof(g_abbv) + _nf_szE * sizeof(name_form))
911746e97e7098def65d59c79d5d661f9a757a837cdphilippe
912746e97e7098def65d59c79d5d661f9a757a837cdphilippe   ta_nf_maxE = 10; // starting with enough for 9 pairs+terminating pair.
913746e97e7098def65d59c79d5d661f9a757a837cdphilippe   ta = ML_(dinfo_zalloc) ("di.readdwarf3.ht_ta_nf", SZ_G_ABBV(ta_nf_maxE));
914746e97e7098def65d59c79d5d661f9a757a837cdphilippe   cc->ht_abbvs = VG_(HT_construct) ("di.readdwarf3.ht_abbvs");
915746e97e7098def65d59c79d5d661f9a757a837cdphilippe
916746e97e7098def65d59c79d5d661f9a757a837cdphilippe   init_Cursor( &c, cc->debug_abbv, 0, cc->barf,
917746e97e7098def65d59c79d5d661f9a757a837cdphilippe               "Overrun whilst parsing .debug_abbrev section(2)" );
918746e97e7098def65d59c79d5d661f9a757a837cdphilippe   while (True) {
919746e97e7098def65d59c79d5d661f9a757a837cdphilippe      ta->abbv_code = get_ULEB128( &c );
920746e97e7098def65d59c79d5d661f9a757a837cdphilippe      if (ta->abbv_code == 0) break; /* end of the table */
921746e97e7098def65d59c79d5d661f9a757a837cdphilippe
922746e97e7098def65d59c79d5d661f9a757a837cdphilippe      ta->atag = get_ULEB128( &c );
923746e97e7098def65d59c79d5d661f9a757a837cdphilippe      ta->has_children = get_UChar( &c );
924746e97e7098def65d59c79d5d661f9a757a837cdphilippe      ta_nf_n = 0;
925746e97e7098def65d59c79d5d661f9a757a837cdphilippe      while (True) {
926746e97e7098def65d59c79d5d661f9a757a837cdphilippe         if (ta_nf_n >= ta_nf_maxE) {
927746e97e7098def65d59c79d5d661f9a757a837cdphilippe            g_abbv *old_ta = ta;
928746e97e7098def65d59c79d5d661f9a757a837cdphilippe            ta = ML_(dinfo_zalloc) ("di.readdwarf3.ht_ta_nf",
929746e97e7098def65d59c79d5d661f9a757a837cdphilippe                                    SZ_G_ABBV(2 * ta_nf_maxE));
930746e97e7098def65d59c79d5d661f9a757a837cdphilippe            ta_nf_maxE = 2 * ta_nf_maxE;
931746e97e7098def65d59c79d5d661f9a757a837cdphilippe            VG_(memcpy) (ta, old_ta, SZ_G_ABBV(ta_nf_n));
932746e97e7098def65d59c79d5d661f9a757a837cdphilippe            ML_(dinfo_free) (old_ta);
933746e97e7098def65d59c79d5d661f9a757a837cdphilippe         }
934746e97e7098def65d59c79d5d661f9a757a837cdphilippe         ta->nf[ta_nf_n].at_name = get_ULEB128( &c );
935746e97e7098def65d59c79d5d661f9a757a837cdphilippe         ta->nf[ta_nf_n].at_form = get_ULEB128( &c );
936746e97e7098def65d59c79d5d661f9a757a837cdphilippe         if (ta->nf[ta_nf_n].at_name == 0 && ta->nf[ta_nf_n].at_form == 0) {
937746e97e7098def65d59c79d5d661f9a757a837cdphilippe            ta_nf_n++;
938746e97e7098def65d59c79d5d661f9a757a837cdphilippe            break;
939746e97e7098def65d59c79d5d661f9a757a837cdphilippe         }
940746e97e7098def65d59c79d5d661f9a757a837cdphilippe        ta_nf_n++;
941746e97e7098def65d59c79d5d661f9a757a837cdphilippe      }
942e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe
943e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      // Initialises the skip_szB/next_nf elements : an element at position
944e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      // i must contain the sum of its own size + the sizes of all elements
945e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      // following i till either the next variable size element, the next
946e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      // sibling element or the end of the DIE.
947e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      ta->nf[ta_nf_n - 1].skip_szB = 0;
948e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      ta->nf[ta_nf_n - 1].next_nf = 0;
949e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      for (i = ta_nf_n - 2; i >= 0; i--) {
950e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         const UInt form_szB = get_Form_szB (cc, (DW_FORM)ta->nf[i].at_form);
951e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe
952e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         if (ta->nf[i+1].at_name == DW_AT_sibling
953e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe             || ta->nf[i+1].skip_szB == VARSZ_FORM) {
954e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe            ta->nf[i].skip_szB = form_szB;
955e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe            ta->nf[i].next_nf  = i+1;
956e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         } else if (form_szB == VARSZ_FORM) {
957e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe            ta->nf[i].skip_szB = form_szB;
958e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe            ta->nf[i].next_nf  = i+1;
959e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         } else {
960e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe            ta->nf[i].skip_szB = ta->nf[i+1].skip_szB + form_szB;
961e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe            ta->nf[i].next_nf  = ta->nf[i+1].next_nf;
962e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         }
963e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      }
964e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe
965746e97e7098def65d59c79d5d661f9a757a837cdphilippe      ht_ta = ML_(dinfo_zalloc) ("di.readdwarf3.ht_ta", SZ_G_ABBV(ta_nf_n));
966746e97e7098def65d59c79d5d661f9a757a837cdphilippe      VG_(memcpy) (ht_ta, ta, SZ_G_ABBV(ta_nf_n));
967746e97e7098def65d59c79d5d661f9a757a837cdphilippe      VG_(HT_add_node) ( cc->ht_abbvs, ht_ta );
968e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      if (TD3) {
969e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         TRACE_D3("  Adding abbv_code %llu TAG  %s [%s] nf %d ",
970e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe                  (ULong) ht_ta->abbv_code, ML_(pp_DW_TAG)(ht_ta->atag),
971e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe                  ML_(pp_DW_children)(ht_ta->has_children),
972e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe                  ta_nf_n);
973e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         TRACE_D3("  ");
974e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         for (i = 0; i < ta_nf_n; i++)
975e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe            TRACE_D3("[%u,%u] ", ta->nf[i].skip_szB, ta->nf[i].next_nf);
976e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         TRACE_D3("\n");
977e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      }
978746e97e7098def65d59c79d5d661f9a757a837cdphilippe   }
979746e97e7098def65d59c79d5d661f9a757a837cdphilippe
980746e97e7098def65d59c79d5d661f9a757a837cdphilippe   ML_(dinfo_free) (ta);
981746e97e7098def65d59c79d5d661f9a757a837cdphilippe   #undef SZ_G_ABBV
982746e97e7098def65d59c79d5d661f9a757a837cdphilippe}
983746e97e7098def65d59c79d5d661f9a757a837cdphilippe
984746e97e7098def65d59c79d5d661f9a757a837cdphilippestatic g_abbv* get_abbv (CUConst* cc, ULong abbv_code)
985746e97e7098def65d59c79d5d661f9a757a837cdphilippe{
986746e97e7098def65d59c79d5d661f9a757a837cdphilippe   g_abbv *abbv;
987746e97e7098def65d59c79d5d661f9a757a837cdphilippe
988746e97e7098def65d59c79d5d661f9a757a837cdphilippe   abbv = VG_(HT_lookup) (cc->ht_abbvs, abbv_code);
989746e97e7098def65d59c79d5d661f9a757a837cdphilippe   if (!abbv)
990746e97e7098def65d59c79d5d661f9a757a837cdphilippe      cc->barf ("abbv_code not found in ht_abbvs table");
991746e97e7098def65d59c79d5d661f9a757a837cdphilippe   return abbv;
992746e97e7098def65d59c79d5d661f9a757a837cdphilippe}
993746e97e7098def65d59c79d5d661f9a757a837cdphilippe
994746e97e7098def65d59c79d5d661f9a757a837cdphilippe/* Free the memory allocated in CUConst. */
995746e97e7098def65d59c79d5d661f9a757a837cdphilippestatic void clear_CUConst (CUConst* cc)
996746e97e7098def65d59c79d5d661f9a757a837cdphilippe{
997746e97e7098def65d59c79d5d661f9a757a837cdphilippe   VG_(HT_destruct) ( cc->ht_abbvs, ML_(dinfo_free));
998746e97e7098def65d59c79d5d661f9a757a837cdphilippe   cc->ht_abbvs = NULL;
999746e97e7098def65d59c79d5d661f9a757a837cdphilippe}
1000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Parse the Compilation Unit header indicated at 'c' and
1002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   initialise 'cc' accordingly. */
1003b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic __attribute__((noinline))
1004b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid parse_CU_Header ( /*OUT*/CUConst* cc,
1005b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                       Bool td3,
1006b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                       Cursor* c,
10075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                       DiSlice escn_debug_abbv,
1008f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj		       Bool type_unit,
1009f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                       Bool alt_info )
1010b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1011b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar  address_size;
10125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   ULong  debug_abbrev_offset;
1013b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1014b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(memset)(cc, 0, sizeof(*cc));
1015b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(c && c->barf);
1016b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   cc->barf = c->barf;
1017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1018b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* initial_length field */
1019b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   cc->unit_length
1020b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      = get_Initial_Length( &cc->is_dw64, c,
1021b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           "parse_CU_Header: invalid initial-length field" );
1022b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1023b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3("   Length:        %lld\n", cc->unit_length );
1024b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1025b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* version */
1026b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   cc->version = get_UShort( c );
1027fba428cd266b8a39db641c5fd9523daa8939bed0tom   if (cc->version != 2 && cc->version != 3 && cc->version != 4)
1028fba428cd266b8a39db641c5fd9523daa8939bed0tom      cc->barf( "parse_CU_Header: is neither DWARF2 nor DWARF3 nor DWARF4" );
1029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3("   Version:       %d\n", (Int)cc->version );
1030b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* debug_abbrev_offset */
1032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   debug_abbrev_offset = get_Dwarfish_UWord( c, cc->is_dw64 );
10335d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (debug_abbrev_offset >= escn_debug_abbv.szB)
1034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf( "parse_CU_Header: invalid debug_abbrev_offset" );
10355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   TRACE_D3("   Abbrev Offset: %lld\n", debug_abbrev_offset );
1036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1037b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* address size.  If this isn't equal to the host word size, just
1038b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      give up.  This makes it safe to assume elsewhere that
103931452303b095a76295b08096b2840276db808b81sewardj      DW_FORM_addr and DW_FORM_ref_addr can be treated as a host
104031452303b095a76295b08096b2840276db808b81sewardj      word. */
1041b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   address_size = get_UChar( c );
1042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (address_size != sizeof(void*))
1043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf( "parse_CU_Header: invalid address_size" );
1044b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3("   Pointer Size:  %d\n", (Int)address_size );
1045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1046d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   cc->is_type_unit = type_unit;
1047f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   cc->is_alt_info = alt_info;
1048d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
1049d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   if (type_unit) {
1050d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      cc->type_signature = get_ULong( c );
1051d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      cc->type_offset = get_Dwarfish_UWord( c, cc->is_dw64 );
1052d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   }
1053d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
10545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   /* Set up cc->debug_abbv to point to the relevant table for this
10555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      CU.  Set its .szB so that at least we can't read off the end of
10565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      the debug_abbrev section -- potentially (and quite likely) too
10575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      big, if this isn't the last table in the section, but at least
10585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      it's safe.
10595d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
10605d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      This amounts to taking debug_abbv_escn and moving the start
10615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      position along by debug_abbrev_offset bytes, hence forming a
10625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      smaller DiSlice which has the same end point.  Since we checked
10635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      just above that debug_abbrev_offset is less than the size of
10645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      debug_abbv_escn, this should leave us with a nonempty slice. */
10655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   vg_assert(debug_abbrev_offset < escn_debug_abbv.szB);
10665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   cc->debug_abbv      = escn_debug_abbv;
10675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   cc->debug_abbv.ioff += debug_abbrev_offset;
10685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   cc->debug_abbv.szB  -= debug_abbrev_offset;
10695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1070746e97e7098def65d59c79d5d661f9a757a837cdphilippe   init_ht_abbvs(cc, td3);
1071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1073d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj/* This represents a single signatured type.  It maps a type signature
1074d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   (a ULong) to a cooked DIE offset.  Objects of this type are stored
1075d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   in the type signature hash table.  */
1076d935068fc7b53c8a826b3436cdfccd5b7d446903sewardjtypedef
1077d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   struct D3SignatureType {
1078d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      struct D3SignatureType *next;
1079d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      UWord data;
1080d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      ULong type_signature;
1081d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      UWord die;
1082d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   }
1083d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   D3SignatureType;
1084d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
1085d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj/* Record a signatured type in the hash table.  */
1086d935068fc7b53c8a826b3436cdfccd5b7d446903sewardjstatic void record_signatured_type ( VgHashTable tab,
1087d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                                     ULong type_signature,
1088d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                                     UWord die )
1089d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj{
1090d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   D3SignatureType *dstype = ML_(dinfo_zalloc) ( "di.readdwarf3.sigtype",
1091d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                                                 sizeof(D3SignatureType) );
1092d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   dstype->data = (UWord) type_signature;
1093d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   dstype->type_signature = type_signature;
1094d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   dstype->die = die;
1095d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   VG_(HT_add_node) ( tab, dstype );
1096d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj}
1097d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
1098d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj/* Given a type signature hash table and a type signature, return the
1099d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   cooked DIE offset of the type.  If the type cannot be found, call
1100d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   BARF.  */
1101d935068fc7b53c8a826b3436cdfccd5b7d446903sewardjstatic UWord lookup_signatured_type ( VgHashTable tab,
1102d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                                      ULong type_signature,
11036bd9dc18c043927c1196caba20a327238a179c42florian                                      void (*barf)( const HChar* ) __attribute__((noreturn)) )
1104d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj{
1105d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   D3SignatureType *dstype = VG_(HT_lookup) ( tab, (UWord) type_signature );
1106d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   /* This may be unwarranted chumminess with the hash table
1107d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      implementation.  */
1108d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   while ( dstype != NULL && dstype->type_signature != type_signature)
1109d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      dstype = dstype->next;
1110d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   if (dstype == NULL) {
1111d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      barf("lookup_signatured_type: could not find signatured type");
1112d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      /*NOTREACHED*/
1113d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      vg_assert(0);
1114d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   }
1115d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   return dstype->die;
1116d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj}
1117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
11195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Represents Form data.  If szB is 1/2/4/8 then the result is in the
11205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   lowest 1/2/4/8 bytes of u.val.  If szB is zero or negative then the
11215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   result is an image section beginning at u.cur and with size -szB.
11225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   No other szB values are allowed. */
11235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjtypedef
11245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   struct {
11255d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      Long szB; // 1, 2, 4, 8 or non-positive values only.
11265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      union { ULong val; DiCursor cur; } u;
11275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   }
11285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   FormContents;
1129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
11305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* From 'c', get the Form data into 'cts'.  Either it gets a 1/2/4/8
11315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   byte scalar value, or (a reference to) zero or more bytes starting
11325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   at a DiCursor.*/
1133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
11345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjvoid get_Form_contents ( /*OUT*/FormContents* cts,
1135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                         CUConst* cc, Cursor* c,
1136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                         Bool td3, DW_FORM form )
1137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
11385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   VG_(bzero_inline)(cts, sizeof(*cts));
1139e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   // !!! keep switch in sync with get_Form_szB. The nr of characters read below
1140e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   // must be computed similarly in get_Form_szB.
1141e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   // The consistency is verified in trace_DIE.
1142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   switch (form) {
1143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_data1:
11445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)(UChar)get_UChar(c);
11455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 1;
11465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%u", (UInt)cts->u.val);
1147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_data2:
11495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)(UShort)get_UShort(c);
11505d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 2;
11515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%u", (UInt)cts->u.val);
1152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_data4:
11545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)(UInt)get_UInt(c);
11555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 4;
11565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%u", (UInt)cts->u.val);
1157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
11580b5bf911d9d40b8dd3130f6043ef7ba68a9f446esewardj      case DW_FORM_data8:
11595d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = get_ULong(c);
11605d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 8;
11615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%llu", cts->u.val);
11620b5bf911d9d40b8dd3130f6043ef7ba68a9f446esewardj         break;
1163fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_sec_offset:
11645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)get_Dwarfish_UWord( c, cc->is_dw64 );
11655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = cc->is_dw64 ? 8 : 4;
11665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%llu", cts->u.val);
1167fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_sdata:
11695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)(Long)get_SLEB128(c);
11705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 8;
11715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%lld", (Long)cts->u.val);
1172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1173fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_udata:
11745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)(Long)get_ULEB128(c);
11755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 8;
11765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("%llu", (Long)cts->u.val);
1177fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_addr:
1179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* note, this is a hack.  DW_FORM_addr is defined as getting
1180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            a word the size of the target machine as defined by the
1181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            address_size field in the CU Header.  However,
1182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            parse_CU_Header() rejects all inputs except those for
1183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            which address_size == sizeof(Word), hence we can just
1184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            treat it as a (host) Word.  */
11855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)(UWord)get_UWord(c);
11865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
11875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("0x%lx", (UWord)cts->u.val);
1188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
118931452303b095a76295b08096b2840276db808b81sewardj
119031452303b095a76295b08096b2840276db808b81sewardj      case DW_FORM_ref_addr:
119131452303b095a76295b08096b2840276db808b81sewardj         /* We make the same word-size assumption as DW_FORM_addr. */
119231452303b095a76295b08096b2840276db808b81sewardj         /* What does this really mean?  From D3 Sec 7.5.4,
119331452303b095a76295b08096b2840276db808b81sewardj            description of "reference", it would appear to reference
119431452303b095a76295b08096b2840276db808b81sewardj            some other DIE, by specifying the offset from the
119531452303b095a76295b08096b2840276db808b81sewardj            beginning of a .debug_info section.  The D3 spec mentions
119631452303b095a76295b08096b2840276db808b81sewardj            that this might be in some other shared object and
119731452303b095a76295b08096b2840276db808b81sewardj            executable.  But I don't see how the name of the other
119831452303b095a76295b08096b2840276db808b81sewardj            object/exe is specified.
119931452303b095a76295b08096b2840276db808b81sewardj
120031452303b095a76295b08096b2840276db808b81sewardj            At least for the DW_FORM_ref_addrs created by icc11, the
120131452303b095a76295b08096b2840276db808b81sewardj            references seem to be within the same object/executable.
120231452303b095a76295b08096b2840276db808b81sewardj            So for the moment we merely range-check, to see that they
120331452303b095a76295b08096b2840276db808b81sewardj            actually do specify a plausible offset within this
120431452303b095a76295b08096b2840276db808b81sewardj            object's .debug_info, and return the value unchanged.
1205ee93cdbee1e6a0db21be1ec4533a4022c9566388sewardj
1206ee93cdbee1e6a0db21be1ec4533a4022c9566388sewardj            In DWARF 2, DW_FORM_ref_addr is address-sized, but in
1207ee93cdbee1e6a0db21be1ec4533a4022c9566388sewardj            DWARF 3 and later, it is offset-sized.
120831452303b095a76295b08096b2840276db808b81sewardj         */
1209ee93cdbee1e6a0db21be1ec4533a4022c9566388sewardj         if (cc->version == 2) {
12105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            cts->u.val = (ULong)(UWord)get_UWord(c);
12115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            cts->szB   = sizeof(UWord);
1212ee93cdbee1e6a0db21be1ec4533a4022c9566388sewardj         } else {
12135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            cts->u.val = get_Dwarfish_UWord(c, cc->is_dw64);
12145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            cts->szB   = cc->is_dw64 ? sizeof(ULong) : sizeof(UInt);
1215ee93cdbee1e6a0db21be1ec4533a4022c9566388sewardj         }
12165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("0x%lx", (UWord)cts->u.val);
12175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (0) VG_(printf)("DW_FORM_ref_addr 0x%lx\n", (UWord)cts->u.val);
12185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (/* the following is surely impossible, but ... */
12195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             !ML_(sli_is_valid)(cc->escn_debug_info)
12205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             || cts->u.val >= (ULong)cc->escn_debug_info.szB) {
122131452303b095a76295b08096b2840276db808b81sewardj            /* Hmm.  Offset is nonsensical for this object's .debug_info
122231452303b095a76295b08096b2840276db808b81sewardj               section.  Be safe and reject it. */
122331452303b095a76295b08096b2840276db808b81sewardj            cc->barf("get_Form_contents: DW_FORM_ref_addr points "
122431452303b095a76295b08096b2840276db808b81sewardj                     "outside .debug_info");
122531452303b095a76295b08096b2840276db808b81sewardj         }
122631452303b095a76295b08096b2840276db808b81sewardj         break;
122731452303b095a76295b08096b2840276db808b81sewardj
1228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_strp: {
1229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* this is an offset into .debug_str */
1230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UWord uw = (UWord)get_Dwarfish_UWord( c, cc->is_dw64 );
12315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (!ML_(sli_is_valid)(cc->escn_debug_str)
12325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             || uw >= cc->escn_debug_str.szB)
123331452303b095a76295b08096b2840276db808b81sewardj            cc->barf("get_Form_contents: DW_FORM_strp "
1234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     "points outside .debug_str");
1235b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* FIXME: check the entire string lies inside debug_str,
1236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            not just the first byte of it. */
12375d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor str
12385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            = ML_(cur_plus)( ML_(cur_from_sli)(cc->escn_debug_str), uw );
1239e0bd5910153720d5d15697db8063d0d4caa59d8fphilippe         if (TD3) {
12405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            HChar* tmp = ML_(cur_read_strdup)(str, "di.getFC.1");
12415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            TRACE_D3("(indirect string, offset: 0x%lx): %s", uw, tmp);
12425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ML_(dinfo_free)(tmp);
12435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
12445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = str;
12455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)(1 + (ULong)ML_(cur_strlen)(str));
1246b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_string: {
12495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor str = get_AsciiZ(c);
1250e0bd5910153720d5d15697db8063d0d4caa59d8fphilippe         if (TD3) {
12515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            HChar* tmp = ML_(cur_read_strdup)(str, "di.getFC.2");
12525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            TRACE_D3("%s", tmp);
12535d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ML_(dinfo_free)(tmp);
12545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
12555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = str;
1256b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* strlen is safe because get_AsciiZ already 'vetted' the
1257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            entire string */
12585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)(1 + (ULong)ML_(cur_strlen)(str));
1259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1261fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_ref1: {
12625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UChar u8   = get_UChar(c);
12635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UWord res  = cc->cu_start_offset + (UWord)u8;
12645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)res;
12655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
1266fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("<%lx>", res);
1267fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1268fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1269fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_ref2: {
12705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UShort u16 = get_UShort(c);
12715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UWord  res = cc->cu_start_offset + (UWord)u16;
12725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)res;
12735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
1274fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("<%lx>", res);
1275fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1276fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_ref4: {
12785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UInt  u32  = get_UInt(c);
12795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UWord res  = cc->cu_start_offset + (UWord)u32;
12805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)res;
12815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
1282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("<%lx>", res);
1283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1285fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_ref8: {
12865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong u64  = get_ULong(c);
12875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UWord res  = cc->cu_start_offset + (UWord)u64;
12885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)res;
12895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
1290fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("<%lx>", res);
1291fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1292fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1293fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_ref_udata: {
12945d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong u64  = get_ULEB128(c);
12955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UWord res  = cc->cu_start_offset + (UWord)u64;
12965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)res;
12975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
1298fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("<%lx>", res);
1299fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1300fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_flag: {
1302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         UChar u8 = get_UChar(c);
1303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("%u", (UInt)u8);
13045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = (ULong)u8;
13055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 1;
1306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1308fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_flag_present:
1309fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("1");
13105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = 1;
13115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = 1;
1312fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      case DW_FORM_block1: {
13145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64b;
13155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64   = (ULong)get_UChar(c);
13165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor block = get_DiCursor_from_Cursor(c);
1317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("%llu byte block: ", u64);
1318b2250d38b573099db3bde67e8f1bbeb789542076sewardj         for (u64b = u64; u64b > 0; u64b--) {
1319b2250d38b573099db3bde67e8f1bbeb789542076sewardj            UChar u8 = get_UChar(c);
1320b2250d38b573099db3bde67e8f1bbeb789542076sewardj            TRACE_D3("%x ", (UInt)u8);
1321b2250d38b573099db3bde67e8f1bbeb789542076sewardj         }
13225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = block;
13235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)u64;
1324b2250d38b573099db3bde67e8f1bbeb789542076sewardj         break;
1325b2250d38b573099db3bde67e8f1bbeb789542076sewardj      }
1326b2250d38b573099db3bde67e8f1bbeb789542076sewardj      case DW_FORM_block2: {
13275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64b;
13285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64   = (ULong)get_UShort(c);
13295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor block = get_DiCursor_from_Cursor(c);
1330b2250d38b573099db3bde67e8f1bbeb789542076sewardj         TRACE_D3("%llu byte block: ", u64);
1331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (u64b = u64; u64b > 0; u64b--) {
1332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            UChar u8 = get_UChar(c);
1333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            TRACE_D3("%x ", (UInt)u8);
1334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
13355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = block;
13365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)u64;
1337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
1338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1339fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_block4: {
13405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64b;
13415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64   = (ULong)get_UInt(c);
13425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor block = get_DiCursor_from_Cursor(c);
1343fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("%llu byte block: ", u64);
1344fba428cd266b8a39db641c5fd9523daa8939bed0tom         for (u64b = u64; u64b > 0; u64b--) {
1345fba428cd266b8a39db641c5fd9523daa8939bed0tom            UChar u8 = get_UChar(c);
1346fba428cd266b8a39db641c5fd9523daa8939bed0tom            TRACE_D3("%x ", (UInt)u8);
1347fba428cd266b8a39db641c5fd9523daa8939bed0tom         }
13485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = block;
13495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)u64;
1350fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1351fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1352fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_exprloc:
1353fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_block: {
13545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64b;
13555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    u64   = (ULong)get_ULEB128(c);
13565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor block = get_DiCursor_from_Cursor(c);
1357fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("%llu byte block: ", u64);
1358fba428cd266b8a39db641c5fd9523daa8939bed0tom         for (u64b = u64; u64b > 0; u64b--) {
1359fba428cd266b8a39db641c5fd9523daa8939bed0tom            UChar u8 = get_UChar(c);
1360fba428cd266b8a39db641c5fd9523daa8939bed0tom            TRACE_D3("%x ", (UInt)u8);
1361fba428cd266b8a39db641c5fd9523daa8939bed0tom         }
13625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = block;
13635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)u64;
1364fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1365fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1366fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_ref_sig8: {
1367fba428cd266b8a39db641c5fd9523daa8939bed0tom         ULong  u64b;
1368d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         ULong  signature = get_ULong (c);
1369d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         ULong  work = signature;
1370fba428cd266b8a39db641c5fd9523daa8939bed0tom         TRACE_D3("8 byte signature: ");
1371fba428cd266b8a39db641c5fd9523daa8939bed0tom         for (u64b = 8; u64b > 0; u64b--) {
1372d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            UChar u8 = work & 0xff;
1373fba428cd266b8a39db641c5fd9523daa8939bed0tom            TRACE_D3("%x ", (UInt)u8);
1374d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            work >>= 8;
1375fba428cd266b8a39db641c5fd9523daa8939bed0tom         }
1376d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* Due to the way that the hash table is constructed, the
1377d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            resulting DIE offset here is already "cooked".  See
1378d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            cook_die_using_form.  */
13795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = lookup_signatured_type (cc->signature_types, signature,
13805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                              c->barf);
13815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = sizeof(UWord);
1382fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
1383fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
1384fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_FORM_indirect:
13855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents (cts, cc, c, td3, (DW_FORM)get_ULEB128(c));
1386fba428cd266b8a39db641c5fd9523daa8939bed0tom         return;
1387fba428cd266b8a39db641c5fd9523daa8939bed0tom
1388f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      case DW_FORM_GNU_ref_alt:
13895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.val = get_Dwarfish_UWord(c, cc->is_dw64);
13905d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = cc->is_dw64 ? sizeof(ULong) : sizeof(UInt);
13915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("0x%lx", (UWord)cts->u.val);
13925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (0) VG_(printf)("DW_FORM_GNU_ref_alt 0x%lx\n", (UWord)cts->u.val);
13935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (/* the following is surely impossible, but ... */
13943e49e4c2cb9a4394fd12780618e50d19d3c3a404mjw             !ML_(sli_is_valid)(cc->escn_debug_info_alt))
13953e49e4c2cb9a4394fd12780618e50d19d3c3a404mjw            cc->barf("get_Form_contents: DW_FORM_GNU_ref_addr used, "
13963e49e4c2cb9a4394fd12780618e50d19d3c3a404mjw                     "but no alternate .debug_info");
13973e49e4c2cb9a4394fd12780618e50d19d3c3a404mjw         else if (cts->u.val >= (ULong)cc->escn_debug_info_alt.szB) {
1398f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            /* Hmm.  Offset is nonsensical for this object's .debug_info
1399f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj               section.  Be safe and reject it. */
14003e49e4c2cb9a4394fd12780618e50d19d3c3a404mjw            cc->barf("get_Form_contents: DW_FORM_GNU_ref_addr points "
1401f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                     "outside alternate .debug_info");
1402f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         }
1403f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         break;
1404f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj
1405f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      case DW_FORM_GNU_strp_alt: {
1406f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         /* this is an offset into alternate .debug_str */
14075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         SizeT uw = (UWord)get_Dwarfish_UWord( c, cc->is_dw64 );
14083e49e4c2cb9a4394fd12780618e50d19d3c3a404mjw         if (!ML_(sli_is_valid)(cc->escn_debug_str_alt))
14093e49e4c2cb9a4394fd12780618e50d19d3c3a404mjw            cc->barf("get_Form_contents: DW_FORM_GNU_strp_alt used, "
14103e49e4c2cb9a4394fd12780618e50d19d3c3a404mjw                     "but no alternate .debug_str");
14113e49e4c2cb9a4394fd12780618e50d19d3c3a404mjw         else if (uw >= cc->escn_debug_str_alt.szB)
1412f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            cc->barf("get_Form_contents: DW_FORM_GNU_strp_alt "
1413f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                     "points outside alternate .debug_str");
1414f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         /* FIXME: check the entire string lies inside debug_str,
1415f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            not just the first byte of it. */
14165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor str
14175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            = ML_(cur_plus)( ML_(cur_from_sli)(cc->escn_debug_str_alt), uw);
1418e0bd5910153720d5d15697db8063d0d4caa59d8fphilippe         if (TD3) {
14195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            HChar* tmp = ML_(cur_read_strdup)(str, "di.getFC.3");
14205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            TRACE_D3("(indirect alt string, offset: 0x%lx): %s", uw, tmp);
14215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ML_(dinfo_free)(tmp);
14225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
14235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur = str;
14245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->szB   = - (Long)(1 + (ULong)ML_(cur_strlen)(str));
1425f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         break;
1426f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      }
1427f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj
1428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      default:
142931452303b095a76295b08096b2840276db808b81sewardj         VG_(printf)(
14305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            "get_Form_contents: unhandled %d (%s) at <%llx>\n",
143131452303b095a76295b08096b2840276db808b81sewardj            form, ML_(pp_DW_FORM)(form), get_position_of_Cursor(c));
1432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         c->barf("get_Form_contents: unhandled DW_FORM");
1433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1436e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippestatic inline UInt sizeof_Dwarfish_UWord (Bool is_dw64)
1437e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe{
1438e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   if (is_dw64)
1439e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      return sizeof(ULong);
1440e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   else
1441e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      return sizeof(UInt);
1442e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe}
1443e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe
1444e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe#define VARSZ_FORM 0xffffffff
1445e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe/* If the form is a fixed length form, return the nr of bytes for this form.
1446e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   If the form is a variable length form, return VARSZ_FORM. */
1447e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippestatic
1448e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippeUInt get_Form_szB (CUConst* cc, DW_FORM form )
1449e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe{
1450e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   // !!! keep switch in sync with get_Form_contents : the nr of bytes
1451e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   // read from a cursor by get_Form_contents must be returned by
1452e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   // the below switch.
1453e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   // The consistency is verified in trace_DIE.
1454e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   switch (form) {
1455e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_data1: return 1;
1456e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_data2: return 2;
1457e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_data4: return 4;
1458e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_data8: return 8;
1459e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_sec_offset:
1460e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         if (cc->is_dw64)
1461e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe            return 8;
1462e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         else
1463e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe            return 4;
1464e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_sdata:
1465e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return VARSZ_FORM;
1466e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_udata:
1467e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return VARSZ_FORM;
1468e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_addr: // See hack in get_Form_contents
1469e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return sizeof(UWord);
1470e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_ref_addr: // See hack in get_Form_contents
1471e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         if (cc->version == 2)
1472e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe            return sizeof(UWord);
1473e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         else
1474e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe            return sizeof_Dwarfish_UWord (cc->is_dw64);
1475e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_strp:
1476e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return sizeof_Dwarfish_UWord (cc->is_dw64);
1477e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_string:
1478e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return VARSZ_FORM;
1479e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_ref1:
1480e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return 1;
1481e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_ref2:
1482e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return 2;
1483e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_ref4:
1484e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return 4;
1485e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_ref8:
1486e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return 8;
1487e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_ref_udata:
1488e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return VARSZ_FORM;
1489e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_flag:
1490e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return 1;
1491e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_flag_present:
1492e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return 0; // !!! special case, no data.
1493e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_block1:
1494e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return VARSZ_FORM;
1495e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_block2:
1496e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return VARSZ_FORM;
1497e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_block4:
1498e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return VARSZ_FORM;
1499e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_exprloc:
1500e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_block:
1501e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return VARSZ_FORM;
1502e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_ref_sig8:
1503e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return 8 + 8;
1504e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_indirect:
1505e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return VARSZ_FORM;
1506e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_GNU_ref_alt:
1507e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return sizeof_Dwarfish_UWord(cc->is_dw64);
1508e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      case DW_FORM_GNU_strp_alt:
1509e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         return sizeof_Dwarfish_UWord(cc->is_dw64);
1510e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      default:
1511e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         VG_(printf)(
1512e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe            "get_Form_szB: unhandled %d (%s)\n",
1513e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe            form, ML_(pp_DW_FORM)(form));
1514e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         cc->barf("get_Form_contents: unhandled DW_FORM");
1515e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   }
1516e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe}
1517e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe
1518e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe/* Skip a DIE as described by abbv.
1519e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   If the DIE has a sibling, *sibling is set to the skipped DIE sibling value. */
1520e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippestatic
1521e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippevoid skip_DIE (UWord  *sibling,
1522e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe               Cursor* c_die,
1523e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe               g_abbv *abbv,
1524e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe               CUConst* cc)
1525e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe{
1526e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   UInt nf_i;
1527e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   FormContents cts;
1528e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   nf_i = 0;
1529e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   while (True) {
1530e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      if (abbv->nf[nf_i].at_name == DW_AT_sibling) {
1531e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         get_Form_contents( &cts, cc, c_die, False /*td3*/,
1532e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe                            (DW_FORM)abbv->nf[nf_i].at_form );
1533e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         if ( cts.szB > 0 )
1534e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe            *sibling = cts.u.val;
1535e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         nf_i++;
1536e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      } else if (abbv->nf[nf_i].skip_szB == VARSZ_FORM) {
1537e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         get_Form_contents( &cts, cc, c_die, False /*td3*/,
1538e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe                            (DW_FORM)abbv->nf[nf_i].at_form );
1539e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         nf_i++;
1540e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      } else {
1541e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         advance_position_of_Cursor (c_die, (ULong)abbv->nf[nf_i].skip_szB);
1542e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         nf_i = abbv->nf[nf_i].next_nf;
1543e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      }
1544e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      if (nf_i == 0)
1545e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         break;
1546e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   }
1547e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe}
1548e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe
1549b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1550b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
1551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
1552b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Parsing of variable-related DIEs                     ---*/
1553b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
1554b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
1555b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1556b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
1557b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct _TempVar {
15587293d2530f8c60c1060f9f003e214cc341d35266philippe      HChar*  name; /* in DebugInfo's .strpool */
1559b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Represent ranges economically.  nRanges is the number of
1560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ranges.  Cases:
1561b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         0: .rngOneMin .rngOneMax .manyRanges are all zero
1562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         1: .rngOneMin .rngOneMax hold the range; .rngMany is NULL
1563b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         2: .rngOneMin .rngOneMax are zero; .rngMany holds the ranges.
1564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         This is merely an optimisation to avoid having to allocate
1565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         and free the XArray in the common (98%) of cases where there
1566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         is zero or one address ranges. */
1567b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord   nRanges;
1568b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr    rngOneMin;
1569b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr    rngOneMax;
15709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      XArray* rngMany; /* of AddrRange.  NON-UNIQUE PTR in AR_DINFO. */
15719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* Do not free .rngMany, since many TempVars will have the same
15729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         value.  Instead the associated storage is to be freed by
15739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         deleting 'rangetree', which stores a single copy of each
15749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         range. */
1575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* --- */
1576b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int     level;
15779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      UWord   typeR; /* a cuOff */
1578b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GExpr*  gexpr; /* for this variable */
1579b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GExpr*  fbGX;  /* to find the frame base of the enclosing fn, if
1580b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        any */
1581666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      UInt    fndn_ix; /* declaring file/dirname index in fndnpool, or 0 */
1582b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int     fLine; /* declaring file line number, or zero */
1583b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* offset in .debug_info, so that abstract instances can be
1584b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         found to satisfy references from concrete instances. */
1585b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord   dioff;
1586b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord   absOri; /* so the absOri fields refer to dioff fields
1587b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                         in some other, related TempVar. */
1588b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1589b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TempVar;
1590b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
15917cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj#define N_D3_VAR_STACK 48
1592b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
1594b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct {
1595b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Contains the range stack: a stack of address ranges, one
1596b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         stack entry for each nested scope.
1597b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Some scope entries are created by function definitions
1599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (DW_AT_subprogram), and for those, we also note the GExpr
1600b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         derived from its DW_AT_frame_base attribute, if any.
1601b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Consequently it should be possible to find, for any
1602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         variable's DIE, the GExpr for the the containing function's
1603b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT_frame_base by scanning back through the stack to find
1604b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         the nearest entry associated with a function.  This somewhat
1605b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         elaborate scheme is provided so as to make it possible to
1606b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         obtain the correct DW_AT_frame_base expression even in the
1607b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         presence of nested functions (or to be more precise, in the
1608b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         presence of nested DW_AT_subprogram DIEs).
1609b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      */
1610b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int     sp; /* [sp] is innermost active entry; sp==-1 for empty
1611b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                     stack */
1612b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      XArray* ranges[N_D3_VAR_STACK]; /* XArray of AddrRange */
1613b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int     level[N_D3_VAR_STACK];  /* D3 DIE levels */
1614b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool    isFunc[N_D3_VAR_STACK]; /* from DW_AT_subprogram? */
1615b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GExpr*  fbGX[N_D3_VAR_STACK];   /* if isFunc, contains the FB
1616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                         expr, else NULL */
1617666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      /* The fndn_ix file name/dirname table.  Is a mapping from dwarf
1618666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         integer index to the index in di->fndnpool. */
1619666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      XArray* /* of UInt* */ fndn_ix_Table;
1620b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   D3VarParser;
1622b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
16236bd9dc18c043927c1196caba20a327238a179c42florianstatic void varstack_show ( D3VarParser* parser, const HChar* str ) {
1624b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Word i, j;
1625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(printf)("  varstack (%s) {\n", str);
1626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i <= parser->sp; i++) {
1627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      XArray* xa = parser->ranges[i];
1628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(xa);
1629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(printf)("    [%ld] (level %d)", i, parser->level[i]);
1630b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (parser->isFunc[i]) {
1631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(printf)(" (fbGX=%p)", parser->fbGX[i]);
1632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else {
1633b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vg_assert(parser->fbGX[i] == NULL);
1634b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1635b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(printf)(": ");
1636b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (VG_(sizeXA)( xa ) == 0) {
1637b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         VG_(printf)("** empty PC range array **");
1638b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else {
1639b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         for (j = 0; j < VG_(sizeXA)( xa ); j++) {
1640b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            AddrRange* range = (AddrRange*) VG_(indexXA)( xa, j );
1641b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            vg_assert(range);
1642a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart            VG_(printf)("[%#lx,%#lx] ", range->aMin, range->aMax);
1643b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
1644b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
1645b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(printf)("\n");
1646b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1647b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(printf)("  }\n");
1648b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Remove from the stack, all entries with .level > 'level' */
1651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
1652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid varstack_preen ( D3VarParser* parser, Bool td3, Int level )
1653b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1654b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool changed = False;
1655b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp < N_D3_VAR_STACK);
1656b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
1657b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(parser->sp >= -1);
1658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (parser->sp == -1) break;
1659b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (parser->level[parser->sp] <= level) break;
1660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (0)
1661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("BBBBAAAA varstack_pop [newsp=%d]\n", parser->sp-1);
1662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(parser->ranges[parser->sp]);
1663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Who allocated this xa?  get_range_list() or
1664b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         unitary_range_list(). */
1665b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(deleteXA)( parser->ranges[parser->sp] );
1666b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parser->ranges[parser->sp] = NULL;
1667b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parser->level[parser->sp]  = 0;
1668b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parser->isFunc[parser->sp] = False;
1669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parser->fbGX[parser->sp]   = NULL;
1670b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parser->sp--;
1671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      changed = True;
1672b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (changed && td3)
1674b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      varstack_show( parser, "after preen" );
1675b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1676b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1677b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void varstack_push ( CUConst* cc,
1678b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                            D3VarParser* parser,
1679b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                            Bool td3,
1680b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                            XArray* ranges, Int level,
1681b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                            Bool    isFunc, GExpr* fbGX ) {
1682b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (0)
1683b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_D3("BBBBAAAA varstack_push[newsp=%d]: %d  %p\n",
1684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            parser->sp+1, level, ranges);
1685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* First we need to zap everything >= 'level', as we are about to
1687b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      replace any previous entry at 'level', so .. */
1688b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   varstack_preen(parser, /*td3*/False, level-1);
1689b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1690b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp >= -1);
1691b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp < N_D3_VAR_STACK);
1692b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (parser->sp == N_D3_VAR_STACK-1)
1693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("varstack_push: N_D3_VAR_STACK is too low; "
1694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               "increase and recompile");
1695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (parser->sp >= 0)
1696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(parser->level[parser->sp] < level);
1697b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->sp++;
1698b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->ranges[parser->sp] == NULL);
1699b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->level[parser->sp]  == 0);
1700b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->isFunc[parser->sp] == False);
1701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->fbGX[parser->sp]   == NULL);
1702b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(ranges != NULL);
1703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (!isFunc) vg_assert(fbGX == NULL);
1704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->ranges[parser->sp] = ranges;
1705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->level[parser->sp]  = level;
1706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->isFunc[parser->sp] = isFunc;
1707b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->fbGX[parser->sp]   = fbGX;
1708e0bd5910153720d5d15697db8063d0d4caa59d8fphilippe   if (TD3)
1709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      varstack_show( parser, "after push" );
1710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1711b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1712b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
17135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* cts is derived from a DW_AT_location and so refers either to a
17145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   location expression or to a location list.  Figure out which, and
17155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   in both cases bundle the expression or location list into a
17165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   so-called GExpr (guarded expression). */
1717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
17185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic GExpr* get_GX ( CUConst* cc, Bool td3, const FormContents* cts )
1719b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1720b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   GExpr* gexpr = NULL;
17215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (cts->szB < 0) {
17225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      /* represents a non-empty in-line location expression, and
17235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cts->u.cur points at the image bytes */
17245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      gexpr = make_singleton_GX( cts->u.cur, (ULong)(- cts->szB) );
1725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1726b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   else
17275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (cts->szB > 0) {
17285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      /* represents a location list.  cts->u.val is the offset of it
17295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         in .debug_loc. */
1730b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (!cc->cu_svma_known)
1731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         cc->barf("get_GX: location list, but CU svma is unknown");
17325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      gexpr = make_general_GX( cc, td3, cts->u.val, cc->cu_svma );
1733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1734b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   else {
1735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(0); /* else caller is bogus */
1736b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1737b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return gexpr;
1738b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1739b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1740666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe/* Returns an xarray* of directory names (indexed by the dwarf dirname
1741666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   integer).
1742666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   If 'compdir' is NULL, entry [0] will be set to "."
1743666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   otherwise entry [0] is set to compdir.
1744666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   Entry [0] basically means "the current directory of the compilation",
1745666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   whatever that means, according to the DWARF3 spec.
1746666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   FIXME??? readdwarf3.c/readdwarf.c have a lot of duplicated code */
1747666ee9df4c2b6d801b199b8168208dbb46573c9dphilippestatic
1748666ee9df4c2b6d801b199b8168208dbb46573c9dphilippeXArray* read_dirname_xa (struct _DebugInfo* di, const HChar *compdir,
1749666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                         Cursor *c,
1750666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                         Bool td3 )
1751666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe{
1752666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   XArray*        dirname_xa;   /* xarray of HChar* dirname */
1753666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   const HChar*   dirname;
1754666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   UInt           compdir_len = 0;
1755666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe
1756666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   dirname_xa = VG_(newXA) (ML_(dinfo_zalloc), "di.rdxa.1", ML_(dinfo_free),
1757666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                            sizeof(HChar*) );
1758666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe
1759666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   if (compdir == NULL) {
1760666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      dirname = ".";
1761666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      compdir_len = 0;
1762666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   } else {
1763666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      dirname = compdir;
1764666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      compdir_len = VG_(strlen)(compdir);
1765666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   }
1766666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   VG_(addToXA) (dirname_xa, &dirname);
1767666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe
1768666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   TRACE_D3(" The Directory Table%s\n",
1769666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            peek_UChar(c) == 0 ? " is empty." : ":" );
1770666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe
1771666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   while (peek_UChar(c) != 0) {
1772666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe
1773666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe#     define NBUF 4096
1774666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      static HChar buf[NBUF];
1775666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      DiCursor cur = get_AsciiZ(c);
1776666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      HChar* data_str = ML_(cur_read_strdup)( cur, "dirname_xa.1" );
1777666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      TRACE_D3("  %s\n", data_str);
1778666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe
1779666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      /* If data_str[0] is '/', then 'data' is an absolute path and we
1780666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         don't mess with it.  Otherwise, if we can, construct the
1781666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         path 'compdir' ++ "/" ++ 'data'. */
1782666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe
1783666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      if (data_str[0] != '/'
1784666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe          /* not an absolute path */
1785666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe          && compdir
1786666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe          /* actually got something sensible for compdir */
1787666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe          && compdir_len
1788666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe             + VG_(strlen)(data_str) + 5/*paranoia*/ < NBUF
1789666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe          /* it's short enough to concatenate */)
1790666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      {
1791666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         buf[0] = 0;
1792666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         VG_(strcat)(buf, compdir);
1793666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         VG_(strcat)(buf, "/");
1794666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         VG_(strcat)(buf, data_str);
1795666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         vg_assert(VG_(strlen)(buf) < NBUF);
1796666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         dirname = ML_(addStr)(di,buf,-1);
1797666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         VG_(addToXA) (dirname_xa, &dirname);
1798666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         if (0) VG_(printf)("rel path  %s\n", buf);
1799666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      } else {
1800666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         /* just use 'data'. */
1801666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         dirname = ML_(addStr)(di,data_str,-1);
1802666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         VG_(addToXA) (dirname_xa, &dirname);
1803666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         if (0) VG_(printf)("abs path  %s\n", data_str);
1804666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      }
1805666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe
1806666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      ML_(dinfo_free)(data_str);
1807666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe
1808666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe#     undef NBUF
1809666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   }
1810666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe
1811666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   TRACE_D3 ("\n");
1812666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe
1813666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   if (get_UChar (c) != 0) {
1814666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      ML_(symerr)(NULL, True,
1815666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                  "could not get NUL at end of DWARF directory table");
1816666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      VG_(deleteXA)(dirname_xa);
1817666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      return NULL;
1818666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   }
1819666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe
1820666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   return dirname_xa;
1821666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe}
1822b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1823b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
1824666ee9df4c2b6d801b199b8168208dbb46573c9dphilippevoid read_filename_table( /*MOD*/XArray* /* of UInt* */ fndn_ix_Table,
1825666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                          HChar* compdir,
18265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                          CUConst* cc, ULong debug_line_offset,
1827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                          Bool td3 )
1828b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
1829b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool   is_dw64;
1830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Cursor c;
1831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Word   i;
1832b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UShort version;
1833b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UChar  opcode_base;
18341636d33c13958b9c0e7d3059cdd5005746418eb2florian   HChar* str;
1835666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   XArray* dirname_xa;   /* xarray of HChar* dirname */
1836666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   ULong  dir_xa_ix;     /* Index in dirname_xa, as read from dwarf info. */
1837666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   HChar* dirname;
1838666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   UInt   fndn_ix;
1839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1840666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   vg_assert(fndn_ix_Table && cc && cc->barf);
18415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (!ML_(sli_is_valid)(cc->escn_debug_line)
18425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj       || cc->escn_debug_line.szB <= debug_line_offset) {
1843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("read_filename_table: .debug_line is missing?");
18445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   }
1845b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
18465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   init_Cursor( &c, cc->escn_debug_line, debug_line_offset, cc->barf,
1847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                "Overrun whilst reading .debug_line section(1)" );
1848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
18494c245e595b9f6300d3120408ca873f7115d9cc7dnjn   /* unit_length = */
1850e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   get_Initial_Length( &is_dw64, &c,
1851e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe                       "read_filename_table: invalid initial-length field" );
1852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   version = get_UShort( &c );
1853fba428cd266b8a39db641c5fd9523daa8939bed0tom   if (version != 2 && version != 3 && version != 4)
1854fba428cd266b8a39db641c5fd9523daa8939bed0tom     cc->barf("read_filename_table: Only DWARF version 2, 3 and 4 line info "
1855b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              "is currently supported.");
18564c245e595b9f6300d3120408ca873f7115d9cc7dnjn   /*header_length              = (ULong)*/ get_Dwarfish_UWord( &c, is_dw64 );
18574c245e595b9f6300d3120408ca873f7115d9cc7dnjn   /*minimum_instruction_length = */ get_UChar( &c );
1858fba428cd266b8a39db641c5fd9523daa8939bed0tom   if (version >= 4)
1859fba428cd266b8a39db641c5fd9523daa8939bed0tom      /*maximum_operations_per_insn = */ get_UChar( &c );
18604c245e595b9f6300d3120408ca873f7115d9cc7dnjn   /*default_is_stmt            = */ get_UChar( &c );
18614c245e595b9f6300d3120408ca873f7115d9cc7dnjn   /*line_base                  = (Char)*/ get_UChar( &c );
18624c245e595b9f6300d3120408ca873f7115d9cc7dnjn   /*line_range                 = */ get_UChar( &c );
1863b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   opcode_base                = get_UChar( &c );
1864b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* skip over "standard_opcode_lengths" */
1865b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 1; i < (Word)opcode_base; i++)
1866b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj     (void)get_UChar( &c );
1867b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1868666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   dirname_xa = read_dirname_xa(cc->di, compdir, &c, td3);
1869b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1870b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Read and record the file names table */
1871666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   vg_assert( VG_(sizeXA)( fndn_ix_Table ) == 0 );
1872b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Add a dummy index-zero entry.  DWARF3 numbers its files
1873b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      from 1, for some reason. */
1874666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   fndn_ix = ML_(addFnDn) ( cc->di, "<unknown_file>", NULL );
1875666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   VG_(addToXA)( fndn_ix_Table, &fndn_ix );
1876b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (peek_UChar(&c) != 0) {
18775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiCursor cur = get_AsciiZ(&c);
18785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      str = ML_(addStrFromCursor)( cc->di, cur );
1879666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      dir_xa_ix = get_ULEB128( &c );
1880666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      if (dirname_xa != NULL
1881666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe          && dir_xa_ix >= 0 && dir_xa_ix < VG_(sizeXA) (dirname_xa))
1882666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         dirname = *(HChar**)VG_(indexXA) ( dirname_xa, dir_xa_ix );
1883666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      else
1884666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         dirname = NULL;
1885666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      fndn_ix = ML_(addFnDn)( cc->di, str, dirname);
1886666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      TRACE_D3("  read_filename_table: %ld fndn_ix %d %s %s\n",
1887666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe               VG_(sizeXA)(fndn_ix_Table), fndn_ix,
1888666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe               dirname, str);
1889666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      VG_(addToXA)( fndn_ix_Table, &fndn_ix );
1890b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      (void)get_ULEB128( &c ); /* skip last mod time */
1891b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      (void)get_ULEB128( &c ); /* file size */
1892b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
1893b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* We're done!  The rest of it is not interesting. */
1894666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   if (dirname_xa != NULL)
1895666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      VG_(deleteXA)(dirname_xa);
1896b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
1897b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
1898a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/* setup_cu_svma to be called when a cu is found at level 0,
1899a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   to establish the cu_svma. */
1900a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic void setup_cu_svma(CUConst* cc, Bool have_lo, Addr ip_lo, Bool td3)
1901a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{
1902a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Addr cu_svma;
1903a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   /* We have potentially more than one type of parser parsing the
1904a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      dwarf information. At least currently, each parser establishes
1905a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      the cu_svma. So, in case cu_svma_known, we check that the same
1906a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      result is obtained by the 2nd parsing of the cu.
1907a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1908a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Alternatively, we could reset cu_svma_known after each parsing
1909a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      and then check that we only see a single DW_TAG_compile_unit DIE
1910a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      at level 0, DWARF3 only allows exactly one top level DIE per
1911a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      CU. */
1912a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1913a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (have_lo)
1914a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      cu_svma = ip_lo;
1915a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   else {
1916a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Now, it may be that this DIE doesn't tell us the CU's
1917a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         SVMA, by way of not having a DW_AT_low_pc.  That's OK --
1918a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         the CU doesn't *have* to have its SVMA specified.
1919a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1920a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         But as per last para D3 spec sec 3.1.1 ("Normal and
1921a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         Partial Compilation Unit Entries", "If the base address
1922a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         (viz, the SVMA) is undefined, then any DWARF entry of
1923a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         structure defined interms of the base address of that
1924a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         compilation unit is not valid.".  So that means, if whilst
1925a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         processing the children of this top level DIE (or their
1926a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         children, etc) we see a DW_AT_range, and cu_svma_known is
1927a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         False, then the DIE that contains it is (per the spec)
1928a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         invalid, and we can legitimately stop and complain. */
1929a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* .. whereas The Reality is, simply assume the SVMA is zero
1930a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if it isn't specified. */
1931a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      cu_svma = 0;
1932a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
1933a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1934a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (cc->cu_svma_known) {
1935a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      vg_assert (cu_svma == cc->cu_svma);
1936a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   } else {
1937a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      cc->cu_svma_known = True;
1938a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      cc->cu_svma = cu_svma;
1939a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (0)
1940a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         TRACE_D3("setup_cu_svma: acquire CU_SVMA of %p\n", (void*) cc->cu_svma);
1941a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
1942a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe}
1943a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
194486be6ed340d2373ffded269f57aa87765430ddccphilippestatic void trace_DIE(
1945a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   DW_TAG dtag,
1946a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UWord posn,
1947a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Int level,
194886be6ed340d2373ffded269f57aa87765430ddccphilippe   UWord saved_die_c_offset,
1949a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   g_abbv *abbv,
1950a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   CUConst* cc)
1951a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{
195286be6ed340d2373ffded269f57aa87765430ddccphilippe   Cursor c;
1953a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   FormContents cts;
1954e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   UWord sibling = 0;
1955a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UInt nf_i;
1956a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Bool  debug_types_flag;
1957a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Bool  alt_flag;
1958e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   Cursor check_skip;
1959e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   UWord check_sibling = 0;
1960a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
1961a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   posn = uncook_die( cc, posn, &debug_types_flag, &alt_flag );
196286be6ed340d2373ffded269f57aa87765430ddccphilippe   init_Cursor (&c,
196386be6ed340d2373ffded269f57aa87765430ddccphilippe                debug_types_flag ? cc->escn_debug_types :
196486be6ed340d2373ffded269f57aa87765430ddccphilippe                alt_flag ? cc->escn_debug_info_alt : cc->escn_debug_info,
196586be6ed340d2373ffded269f57aa87765430ddccphilippe                saved_die_c_offset, cc->barf,
196686be6ed340d2373ffded269f57aa87765430ddccphilippe                "Overrun trace_DIE");
1967e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   check_skip = c;
196886be6ed340d2373ffded269f57aa87765430ddccphilippe   VG_(printf)(" <%d><%lx>: Abbrev Number: %llu (%s)%s%s\n",
196986be6ed340d2373ffded269f57aa87765430ddccphilippe               level, posn, (ULong) abbv->abbv_code, ML_(pp_DW_TAG)( dtag ),
197086be6ed340d2373ffded269f57aa87765430ddccphilippe               debug_types_flag ? " (in .debug_types)" : "",
197186be6ed340d2373ffded269f57aa87765430ddccphilippe               alt_flag ? " (in alternate .debug_info)" : "");
1972a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   nf_i = 0;
1973a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   while (True) {
1974a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
1975a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
1976a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      nf_i++;
1977a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (attr == 0 && form == 0) break;
1978a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(printf)("     %18s: ", ML_(pp_DW_AT)(attr));
1979a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Get the form contents, so as to print them */
198086be6ed340d2373ffded269f57aa87765430ddccphilippe      get_Form_contents( &cts, cc, &c, True, form );
1981e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      if (attr == DW_AT_sibling && cts.szB > 0) {
1982e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         sibling = cts.u.val;
1983e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      }
1984a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(printf)("\t\n");
1985a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
1986e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe
1987e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   /* Verify that skipping a DIE gives the same displacement as
1988e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      tracing (i.e. reading) a DIE. If there is an inconsistency in
1989e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      the nr of bytes read by get_Form_contents and get_Form_szB, this
1990e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      should be detected by the below. Using --trace-symtab=yes
1991e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      --read-var-info=yes will ensure all DIEs are systematically
1992e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      verified. */
1993e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   skip_DIE (&check_sibling, &check_skip, abbv, cc);
1994e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   vg_assert (check_sibling == sibling);
1995e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe   vg_assert (get_position_of_Cursor (&check_skip)
1996e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe              == get_position_of_Cursor (&c));
199786be6ed340d2373ffded269f57aa87765430ddccphilippe}
199886be6ed340d2373ffded269f57aa87765430ddccphilippe
199986be6ed340d2373ffded269f57aa87765430ddccphilippe__attribute__((noreturn))
200086be6ed340d2373ffded269f57aa87765430ddccphilippestatic void dump_bad_die_and_barf(
200186be6ed340d2373ffded269f57aa87765430ddccphilippe   const HChar *whichparser,
200286be6ed340d2373ffded269f57aa87765430ddccphilippe   DW_TAG dtag,
200386be6ed340d2373ffded269f57aa87765430ddccphilippe   UWord posn,
200486be6ed340d2373ffded269f57aa87765430ddccphilippe   Int level,
200586be6ed340d2373ffded269f57aa87765430ddccphilippe   Cursor* c_die,
200686be6ed340d2373ffded269f57aa87765430ddccphilippe   UWord saved_die_c_offset,
200786be6ed340d2373ffded269f57aa87765430ddccphilippe   g_abbv *abbv,
200886be6ed340d2373ffded269f57aa87765430ddccphilippe   CUConst* cc)
200986be6ed340d2373ffded269f57aa87765430ddccphilippe{
201086be6ed340d2373ffded269f57aa87765430ddccphilippe   trace_DIE (dtag, posn, level, saved_die_c_offset, abbv, cc);
201186be6ed340d2373ffded269f57aa87765430ddccphilippe   VG_(printf)("%s:\n", whichparser);
2012896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe   cc->barf("confused by the above DIE");
2013a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe}
2014a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
20155c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe__attribute__((noinline))
20165c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippestatic void bad_DIE_confusion(int linenr)
20175c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe{
2018896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe   VG_(printf)("\nparse DIE(readdwarf3.c:%d): confused by:\n", linenr);
20195c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe}
20205c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe#define goto_bad_DIE do {bad_DIE_confusion(__LINE__); goto bad_DIE;} while (0)
2021b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2022b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
20239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic void parse_var_DIE (
20249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/WordFM* /* of (XArray* of AddrRange, void) */ rangestree,
20259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/XArray* /* of TempVar* */ tempvars,
20269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/XArray* /* of GExpr* */ gexprs,
20279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/D3VarParser* parser,
20289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   DW_TAG dtag,
20299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   UWord posn,
20309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Int level,
20319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Cursor* c_die,
2032746e97e7098def65d59c79d5d661f9a757a837cdphilippe   g_abbv *abbv,
20339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   CUConst* cc,
20349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Bool td3
20359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj)
2036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
20375d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   FormContents cts;
2038746e97e7098def65d59c79d5d661f9a757a837cdphilippe   UInt nf_i;
2039b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2040b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UWord saved_die_c_offset  = get_position_of_Cursor( c_die );
2041b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   varstack_preen( parser, td3, level-1 );
2043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2044f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   if (dtag == DW_TAG_compile_unit
2045f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj       || dtag == DW_TAG_type_unit
2046f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj       || dtag == DW_TAG_partial_unit) {
2047b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_lo    = False;
2048b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_hi1   = False;
2049de065a05bd7e802669c9074b129268bd9a5c308csewardj      Bool hiIsRelative = False;
2050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_range = False;
2051b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr ip_lo    = 0;
2052b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr ip_hi1   = 0;
2053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr rangeoff = 0;
2054666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      HChar *compdir = NULL;
2055746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
2056b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2057746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
2058746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
2059746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
2060b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
20615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
20625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_low_pc && cts.szB > 0) {
20635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ip_lo   = cts.u.val;
2064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_lo = True;
2065b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
20665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_high_pc && cts.szB > 0) {
20675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ip_hi1   = cts.u.val;
2068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_hi1 = True;
2069de065a05bd7e802669c9074b129268bd9a5c308csewardj            if (form != DW_FORM_addr)
2070de065a05bd7e802669c9074b129268bd9a5c308csewardj               hiIsRelative = True;
2071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
20725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_ranges && cts.szB > 0) {
20735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            rangeoff   = cts.u.val;
2074b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_range = True;
2075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2076666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         if (attr == DW_AT_comp_dir) {
2077666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            if (cts.szB >= 0)
2078666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe               cc->barf("parse_var_DIE compdir: expecting indirect string");
2079666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            HChar *str = ML_(cur_read_strdup)( cts.u.cur,
2080666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                                               "parse_var_DIE.compdir" );
2081666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            compdir = ML_(addStr)(cc->di, str, -1);
2082666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            ML_(dinfo_free) (str);
2083666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         }
20845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_stmt_list && cts.szB > 0) {
2085666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            read_filename_table( parser->fndn_ix_Table, compdir,
2086666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                                 cc, cts.u.val, td3 );
2087b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2088b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2089de065a05bd7e802669c9074b129268bd9a5c308csewardj      if (have_lo && have_hi1 && hiIsRelative)
2090de065a05bd7e802669c9074b129268bd9a5c308csewardj         ip_hi1 += ip_lo;
2091a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2092b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Now, does this give us an opportunity to find this
2093b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         CU's svma? */
2094a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (level == 0)
2095a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         setup_cu_svma(cc, have_lo, ip_lo, td3);
2096a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2097b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
2098b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (have_lo && have_hi1 && (!have_range)) {
2099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (ip_lo < ip_hi1)
2100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            varstack_push( cc, parser, td3,
2101b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           unitary_range_list(ip_lo, ip_hi1 - 1),
2102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           level,
2103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           False/*isFunc*/, NULL/*fbGX*/ );
21048130f91dc99a9ad90e516f8b449970ddaeaee911philippe         else if (ip_lo == 0 && ip_hi1 == 0)
21058130f91dc99a9ad90e516f8b449970ddaeaee911philippe            /* CU has no code, presumably?
21068130f91dc99a9ad90e516f8b449970ddaeaee911philippe               Such situations have been encountered for code
21078130f91dc99a9ad90e516f8b449970ddaeaee911philippe               compiled with -ffunction-sections -fdata-sections
21088130f91dc99a9ad90e516f8b449970ddaeaee911philippe               and linked with --gc-sections. Completely
21098130f91dc99a9ad90e516f8b449970ddaeaee911philippe               eliminated CU gives such 0 lo/hi pc. Similarly
21108130f91dc99a9ad90e516f8b449970ddaeaee911philippe               to a CU which has no lo/hi/range pc, we push
21118130f91dc99a9ad90e516f8b449970ddaeaee911philippe               an empty range list. */
21128130f91dc99a9ad90e516f8b449970ddaeaee911philippe            varstack_push( cc, parser, td3,
21138130f91dc99a9ad90e516f8b449970ddaeaee911philippe                           empty_range_list(),
21148130f91dc99a9ad90e516f8b449970ddaeaee911philippe                           level,
21158130f91dc99a9ad90e516f8b449970ddaeaee911philippe                           False/*isFunc*/, NULL/*fbGX*/ );
2116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
2117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if ((!have_lo) && (!have_hi1) && have_range) {
2118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         varstack_push( cc, parser, td3,
2119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        get_range_list( cc, td3,
2120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                        rangeoff, cc->cu_svma ),
2121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        level,
2122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        False/*isFunc*/, NULL/*fbGX*/ );
2123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
2124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if ((!have_lo) && (!have_hi1) && (!have_range)) {
2125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* CU has no code, presumably? */
2126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         varstack_push( cc, parser, td3,
2127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        empty_range_list(),
2128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        level,
2129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        False/*isFunc*/, NULL/*fbGX*/ );
2130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
2131f578a69a862391896fa2f03359c3744022ae9783sewardj      if (have_lo && (!have_hi1) && have_range && ip_lo == 0) {
2132f578a69a862391896fa2f03359c3744022ae9783sewardj         /* broken DIE created by gcc-4.3.X ?  Ignore the
2133f578a69a862391896fa2f03359c3744022ae9783sewardj            apparently-redundant DW_AT_low_pc and use the DW_AT_ranges
2134f578a69a862391896fa2f03359c3744022ae9783sewardj            instead. */
2135f578a69a862391896fa2f03359c3744022ae9783sewardj         varstack_push( cc, parser, td3,
2136f578a69a862391896fa2f03359c3744022ae9783sewardj                        get_range_list( cc, td3,
2137f578a69a862391896fa2f03359c3744022ae9783sewardj                                        rangeoff, cc->cu_svma ),
2138f578a69a862391896fa2f03359c3744022ae9783sewardj                        level,
2139f578a69a862391896fa2f03359c3744022ae9783sewardj                        False/*isFunc*/, NULL/*fbGX*/ );
2140f578a69a862391896fa2f03359c3744022ae9783sewardj      } else {
2141f578a69a862391896fa2f03359c3744022ae9783sewardj         if (0) VG_(printf)("I got hlo %d hhi1 %d hrange %d\n",
2142f578a69a862391896fa2f03359c3744022ae9783sewardj                            (Int)have_lo, (Int)have_hi1, (Int)have_range);
21435c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
2144f578a69a862391896fa2f03359c3744022ae9783sewardj      }
2145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_lexical_block || dtag == DW_TAG_subprogram) {
2148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   have_lo    = False;
2149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   have_hi1   = False;
2150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   have_range = False;
2151de065a05bd7e802669c9074b129268bd9a5c308csewardj      Bool   hiIsRelative = False;
2152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr   ip_lo      = 0;
2153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr   ip_hi1     = 0;
2154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Addr   rangeoff   = 0;
2155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   isFunc     = dtag == DW_TAG_subprogram;
2156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GExpr* fbGX       = NULL;
2157746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
2158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2159746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
2160746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
2161746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
2162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
21635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
21645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_low_pc && cts.szB > 0) {
21655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ip_lo   = cts.u.val;
2166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_lo = True;
2167b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
21685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_high_pc && cts.szB > 0) {
21695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ip_hi1   = cts.u.val;
2170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_hi1 = True;
2171de065a05bd7e802669c9074b129268bd9a5c308csewardj            if (form != DW_FORM_addr)
2172de065a05bd7e802669c9074b129268bd9a5c308csewardj               hiIsRelative = True;
2173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
21745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_ranges && cts.szB > 0) {
21755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            rangeoff   = cts.u.val;
2176b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_range = True;
2177b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2178b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (isFunc
2179b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             && attr == DW_AT_frame_base
21805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             && cts.szB != 0 /* either scalar or nonempty block */) {
21815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            fbGX = get_GX( cc, False/*td3*/, &cts );
2182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            vg_assert(fbGX);
218359a2d18d0ddfa241850017252b0804d469187d79sewardj            VG_(addToXA)(gexprs, &fbGX);
2184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2185b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2186de065a05bd7e802669c9074b129268bd9a5c308csewardj      if (have_lo && have_hi1 && hiIsRelative)
2187de065a05bd7e802669c9074b129268bd9a5c308csewardj         ip_hi1 += ip_lo;
2188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
2189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (dtag == DW_TAG_subprogram
2190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          && (!have_lo) && (!have_hi1) && (!have_range)) {
2191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* This is legit - ignore it. Sec 3.3.3: "A subroutine entry
2192b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            representing a subroutine declaration that is not also a
2193b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            definition does not have code address or range
2194b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            attributes." */
2195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
2196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (dtag == DW_TAG_lexical_block
2197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          && (!have_lo) && (!have_hi1) && (!have_range)) {
2198b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* I believe this is legit, and means the lexical block
2199b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            contains no insns (whatever that might mean).  Ignore. */
2200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
2201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (have_lo && have_hi1 && (!have_range)) {
2202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* This scope supplies just a single address range. */
2203b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (ip_lo < ip_hi1)
2204b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            varstack_push( cc, parser, td3,
2205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           unitary_range_list(ip_lo, ip_hi1 - 1),
2206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                           level, isFunc, fbGX );
2207b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
2208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if ((!have_lo) && (!have_hi1) && have_range) {
2209b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* This scope supplies multiple address ranges via the use of
2210b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            a range list. */
2211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         varstack_push( cc, parser, td3,
2212b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        get_range_list( cc, td3,
2213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                        rangeoff, cc->cu_svma ),
2214b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                        level, isFunc, fbGX );
2215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
2216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (have_lo && (!have_hi1) && (!have_range)) {
2217b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* This scope is bogus.  The D3 spec sec 3.4 (Lexical Block
2218b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Entries) says fairly clearly that a scope must have either
2219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            _range or (_low_pc and _high_pc). */
2220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* The spec is a bit ambiguous though.  Perhaps a single byte
2221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            range is intended?  See sec 2.17 (Code Addresses And Ranges) */
2222b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* This case is here because icc9 produced this:
2223b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         <2><13bd>: DW_TAG_lexical_block
2224b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            DW_AT_decl_line   : 5229
2225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            DW_AT_decl_column : 37
2226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            DW_AT_decl_file   : 1
2227b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            DW_AT_low_pc      : 0x401b03
2228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         */
2229b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* Ignore (seems safe than pushing a single byte range) */
2230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else
22315c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
2232b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2233b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2234b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_variable || dtag == DW_TAG_formal_parameter) {
22351636d33c13958b9c0e7d3059cdd5005746418eb2florian      HChar* name        = NULL;
22369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      UWord  typeR       = D3_INVALID_CUOFF;
223781d24c396c66dde7db2d9b567451f99081a2eab7philippe      Bool   global      = False;
2238b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      GExpr* gexpr       = NULL;
2239b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int    n_attrs     = 0;
2240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UWord  abs_ori     = (UWord)D3_INVALID_CUOFF;
2241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int    lineNo      = 0;
2242666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      UInt   fndn_ix     = 0;
2243746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
2244b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2245746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
2246746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
2247746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
2248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
22495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
2250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         n_attrs++;
22515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
22525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            name = ML_(addStrFromCursor)( cc->di, cts.u.cur );
2253b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2254b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == DW_AT_location
22555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             && cts.szB != 0 /* either scalar or nonempty block */) {
22565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            gexpr = get_GX( cc, False/*td3*/, &cts );
2257b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            vg_assert(gexpr);
225859a2d18d0ddfa241850017252b0804d469187d79sewardj            VG_(addToXA)(gexprs, &gexpr);
2259b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
22605d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_type && cts.szB > 0) {
22615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeR = cook_die_using_form( cc, cts.u.val, form );
2262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
22635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_external && cts.szB > 0 && cts.u.val > 0) {
226481d24c396c66dde7db2d9b567451f99081a2eab7philippe            global = True;
2265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
22665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_abstract_origin && cts.szB > 0) {
22675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            abs_ori = (UWord)cts.u.val;
2268b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
22695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_declaration && cts.szB > 0 && cts.u.val > 0) {
22704c245e595b9f6300d3120408ca873f7115d9cc7dnjn            /*declaration = True;*/
2271b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
22725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_decl_line && cts.szB > 0) {
22735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            lineNo = (Int)cts.u.val;
2274b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
22755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_decl_file && cts.szB > 0) {
22765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            Int ftabIx = (Int)cts.u.val;
2277b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (ftabIx >= 1
2278666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                && ftabIx < VG_(sizeXA)( parser->fndn_ix_Table )) {
2279666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe               fndn_ix = *(UInt*)VG_(indexXA)( parser->fndn_ix_Table, ftabIx );
2280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
2281666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            if (0) VG_(printf)("XXX filename fndn_ix = %d %s\n", fndn_ix,
2282666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                               ML_(fndn_ix2filename) (cc->di, fndn_ix));
2283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2284b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
228581d24c396c66dde7db2d9b567451f99081a2eab7philippe      if (!global && dtag == DW_TAG_variable && level == 1) {
228681d24c396c66dde7db2d9b567451f99081a2eab7philippe         /* Case of a static variable. It is better to declare
228781d24c396c66dde7db2d9b567451f99081a2eab7philippe            it global as the variable is not really related to
228881d24c396c66dde7db2d9b567451f99081a2eab7philippe            a PC range, as its address can be used by program
228981d24c396c66dde7db2d9b567451f99081a2eab7philippe            counters outside of the ranges where it is visible . */
229081d24c396c66dde7db2d9b567451f99081a2eab7philippe         global = True;
229181d24c396c66dde7db2d9b567451f99081a2eab7philippe      }
229281d24c396c66dde7db2d9b567451f99081a2eab7philippe
2293b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* We'll collect it under if one of the following three
2294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         conditions holds:
2295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (1) has location and type    -> completed
2296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (2) has type only            -> is an abstract instance
2297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (3) has location and abs_ori -> is a concrete instance
2298666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         Name, fndn_ix and line number are all optional frills.
2299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      */
2300b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if ( /* 1 */ (gexpr && typeR != D3_INVALID_CUOFF)
2301b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           /* 2 */ || (typeR != D3_INVALID_CUOFF)
2302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           /* 3 */ || (gexpr && abs_ori != (UWord)D3_INVALID_CUOFF) ) {
2303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2304b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* Add this variable to the list of interesting looking
2305b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            variables.  Crucially, note along with it the address
2306b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            range(s) associated with the variable, which for locals
2307b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            will be the address ranges at the top of the varparser's
2308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            stack. */
2309b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         GExpr*   fbGX = NULL;
2310b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Word     i, nRanges;
2311b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         XArray*  /* of AddrRange */ xa;
2312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TempVar* tv;
2313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* Stack can't be empty; we put a dummy entry on it for the
2314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            entire address range before starting with the DIEs for
2315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            this CU. */
2316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vg_assert(parser->sp >= 0);
2317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
231881d24c396c66dde7db2d9b567451f99081a2eab7philippe         /* If this is a local variable (non-global), try to find
2319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            the GExpr for the DW_AT_frame_base of the containing
2320b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            function.  It should have been pushed on the stack at the
2321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            time we encountered its DW_TAG_subprogram DIE, so the way
2322b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            to find it is to scan back down the stack looking for it.
2323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            If there isn't an enclosing stack entry marked 'isFunc'
2324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            then we must be seeing variable or formal param DIEs
2325b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            outside of a function, so we deem the Dwarf to be
2326b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            malformed if that happens.  Note that the fbGX may be NULL
2327b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if the containing DT_TAG_subprogram didn't supply a
2328b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            DW_AT_frame_base -- that's OK, but there must actually be
2329b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            a containing DW_TAG_subprogram. */
233081d24c396c66dde7db2d9b567451f99081a2eab7philippe         if (!global) {
2331b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Bool found = False;
2332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            for (i = parser->sp; i >= 0; i--) {
2333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (parser->isFunc[i]) {
2334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  fbGX = parser->fbGX[i];
2335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  found = True;
2336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  break;
2337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               }
2338b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
2339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (!found) {
2340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               if (0 && VG_(clo_verbosity) >= 0) {
2341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  VG_(message)(Vg_DebugMsg,
234281d24c396c66dde7db2d9b567451f99081a2eab7philippe                     "warning: parse_var_DIE: non-global variable "
2343738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                     "outside DW_TAG_subprogram\n");
2344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               }
23455c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe               /* goto_bad_DIE; */
2346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               /* This seems to happen a lot.  Just ignore it -- if,
2347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  when we come to evaluation of the location (guarded)
2348b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  expression, it requires a frame base value, and
2349b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  there's no expression for that, then evaluation as a
2350b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  whole will fail.  Harmless - a bit of a waste of
2351b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  cycles but nothing more. */
2352b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
2353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2354b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
235581d24c396c66dde7db2d9b567451f99081a2eab7philippe         /* re "global ? 0 : parser->sp" (twice), if the var is
235681d24c396c66dde7db2d9b567451f99081a2eab7philippe            marked 'global' then we must put it at the global scope,
2357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            as only the global scope (level 0) covers the entire PC
2358b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            address space.  It is asserted elsewhere that level 0
2359b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            always covers the entire address space. */
236081d24c396c66dde7db2d9b567451f99081a2eab7philippe         xa = parser->ranges[global ? 0 : parser->sp];
2361b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         nRanges = VG_(sizeXA)(xa);
2362b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         vg_assert(nRanges >= 0);
2363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
23649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         tv = ML_(dinfo_zalloc)( "di.readdwarf3.pvD.1", sizeof(TempVar) );
2365b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->name   = name;
236681d24c396c66dde7db2d9b567451f99081a2eab7philippe         tv->level  = global ? 0 : parser->sp;
2367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->typeR  = typeR;
2368b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->gexpr  = gexpr;
2369b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->fbGX   = fbGX;
2370666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         tv->fndn_ix= fndn_ix;
2371b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->fLine  = lineNo;
2372b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->dioff  = posn;
2373b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->absOri = abs_ori;
2374b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2375b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* See explanation on definition of type TempVar for the
2376b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            reason for this elaboration. */
2377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->nRanges = nRanges;
2378b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->rngOneMin = 0;
2379b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->rngOneMax = 0;
2380b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         tv->rngMany = NULL;
2381b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (nRanges == 1) {
2382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            AddrRange* range = VG_(indexXA)(xa, 0);
2383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            tv->rngOneMin = range->aMin;
2384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            tv->rngOneMax = range->aMax;
2385b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2386b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         else if (nRanges > 1) {
23879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            /* See if we already have a range list which is
23889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               structurally identical.  If so, use that; if not, clone
23899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               this one, and add it to our collection. */
23909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            UWord keyW, valW;
23919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            if (VG_(lookupFM)( rangestree, &keyW, &valW, (UWord)xa )) {
23929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               XArray* old = (XArray*)keyW;
23939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               tl_assert(valW == 0);
23949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               tl_assert(old != xa);
23959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               tv->rngMany = old;
23969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            } else {
23979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               XArray* cloned = VG_(cloneXA)( "di.readdwarf3.pvD.2", xa );
23989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               tv->rngMany = cloned;
23999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               VG_(addToFM)( rangestree, (UWord)cloned, 0 );
24009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            }
2401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2402b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
240359a2d18d0ddfa241850017252b0804d469187d79sewardj         VG_(addToXA)( tempvars, &tv );
2404b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2405b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("  Recording this variable, with %ld PC range(s)\n",
2406b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  VG_(sizeXA)(xa) );
2407b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* collect stats on how effective the ->ranges special
2408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            casing is */
2409b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (0) {
24109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            static Int ntot=0, ngt=0;
24119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            ntot++;
24129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            if (tv->rngMany) ngt++;
24139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            if (0 == (ntot % 100000))
24149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               VG_(printf)("XXXX %d tot, %d cloned\n", ntot, ngt);
2415b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2416b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2417b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2418b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2419b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Here are some other weird cases seen in the wild:
2420b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            We have a variable with a name and a type, but no
2422b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            location.  I guess that's a sign that it has been
2423b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            optimised away.  Ignore it.  Here's an example:
2424b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2425b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            static Int lc_compar(void* n1, void* n2) {
2426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               MC_Chunk* mc1 = *(MC_Chunk**)n1;
2427b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               MC_Chunk* mc2 = *(MC_Chunk**)n2;
2428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               return (mc1->data < mc2->data ? -1 : 1);
2429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
2430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Both mc1 and mc2 are like this
2432b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            <2><5bc>: Abbrev Number: 21 (DW_TAG_variable)
2433b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_name        : mc1
2434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_decl_file   : 1
2435b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_decl_line   : 216
2436b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_type        : <5d3>
2437b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2438b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            whereas n1 and n2 do have locations specified.
2439b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2440b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ---------------------------------------------
2441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2442b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            We see a DW_TAG_formal_parameter with a type, but
2443b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            no name and no location.  It's probably part of a function type
2444b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            construction, thusly, hence ignore it:
2445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         <1><2b4>: Abbrev Number: 12 (DW_TAG_subroutine_type)
2446b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_sibling     : <2c9>
2447b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_prototyped  : 1
2448b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_type        : <114>
2449b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         <2><2be>: Abbrev Number: 13 (DW_TAG_formal_parameter)
2450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_type        : <13e>
2451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         <2><2c3>: Abbrev Number: 13 (DW_TAG_formal_parameter)
2452b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_type        : <133>
2453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ---------------------------------------------
2455b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Is very minimal, like this:
2457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            <4><81d>: Abbrev Number: 44 (DW_TAG_variable)
2458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_abstract_origin: <7ba>
2459b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            What that signifies I have no idea.  Ignore.
2460b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2461b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ----------------------------------------------
2462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Is very minimal, like this:
2464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            <200f>: DW_TAG_formal_parameter
2465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_abstract_ori: <1f4c>
2466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                DW_AT_location    : 13440
2467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            What that signifies I have no idea.  Ignore.
2468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            It might be significant, though: the variable at least
2469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            has a location and so might exist somewhere.
2470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Maybe we should handle this.
2471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2472b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            ---------------------------------------------
2473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2474b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            <22407>: DW_TAG_variable
2475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              DW_AT_name        : (indirect string, offset: 0x6579):
2476b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                  vgPlain_trampoline_stuff_start
2477b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              DW_AT_decl_file   : 29
2478b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              DW_AT_decl_line   : 56
2479b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              DW_AT_external    : 1
2480b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              DW_AT_declaration : 1
2481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2482b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            Nameless and typeless variable that has a location?  Who
2483b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            knows.  Not me.
2484b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            <2><3d178>: Abbrev Number: 22 (DW_TAG_variable)
2485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                 DW_AT_location    : 9 byte block: 3 c0 c7 13 38 0 0 0 0
2486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                     (DW_OP_addr: 3813c7c0)
2487b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2488b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            No, really.  Check it out.  gcc is quite simply borked.
2489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            <3><168cc>: Abbrev Number: 141 (DW_TAG_variable)
2490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            // followed by no attributes, and the next DIE is a sibling,
2491b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            // not a child
2492b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            */
2493b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2494b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return;
2495b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2496b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  bad_DIE:
2497896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe   dump_bad_die_and_barf("parse_var_DIE", dtag, posn, level,
2498a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                         c_die, saved_die_c_offset,
2499a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                         abbv,
2500a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                         cc);
2501a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   /*NOTREACHED*/
2502a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe}
2503a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2504a0a73939b0398b6608fd6dbde49820ce6530d12cphilippetypedef
2505a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   struct {
2506666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      /* The fndn_ix file name/dirname table.  Is a mapping from dwarf
2507666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         integer index to the index in di->fndnpool. */
2508666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      XArray* /* of UInt* */ fndn_ix_Table;
2509d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe      UWord sibling; // sibling of the last read DIE (if it has a sibling).
2510f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   }
2511a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   D3InlParser;
2512a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2513a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/* Return the function name corresponding to absori.
2514a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   The return value is a (permanent) string in DebugInfo's .strchunks. */
2515a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic HChar* get_inlFnName (Int absori, CUConst* cc, Bool td3)
2516a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{
2517a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Cursor c;
2518a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   g_abbv *abbv;
2519a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   ULong  atag, abbv_code;
2520a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UInt   has_children;
2521a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UWord  posn;
2522a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   HChar *ret = NULL;
2523a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   FormContents cts;
2524a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UInt nf_i;
2525a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2526a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   init_Cursor (&c, cc->escn_debug_info, absori, cc->barf,
2527a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                "Overrun get_inlFnName absori");
2528a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2529a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   posn      = cook_die( cc, get_position_of_Cursor( &c ) );
2530a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   abbv_code = get_ULEB128( &c );
2531a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   abbv      = get_abbv ( cc, abbv_code);
2532a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   atag      = abbv->atag;
2533a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   TRACE_D3(" <get_inlFnName><%lx>: Abbrev Number: %llu (%s)\n",
2534a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            posn, abbv_code, ML_(pp_DW_TAG)( atag ) );
2535a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2536a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (atag == 0)
2537a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      cc->barf("get_inlFnName: invalid zero tag on DIE");
2538a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2539a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   has_children = abbv->has_children;
2540a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (has_children != DW_children_no && has_children != DW_children_yes)
2541a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      cc->barf("get_inlFnName: invalid has_children value");
2542a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2543a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (atag != DW_TAG_subprogram)
2544a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      cc->barf("get_inlFnName: absori not a subprogram");
2545a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2546746e97e7098def65d59c79d5d661f9a757a837cdphilippe   nf_i = 0;
2547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
2548746e97e7098def65d59c79d5d661f9a757a837cdphilippe      DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
2549746e97e7098def65d59c79d5d661f9a757a837cdphilippe      DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
2550746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i++;
2551b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (attr == 0 && form == 0) break;
2552a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      get_Form_contents( &cts, cc, &c, False/*td3*/, form );
2553a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (attr == DW_AT_name) {
2554a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         HChar *fnname;
2555a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (cts.szB >= 0)
2556a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            cc->barf("get_inlFnName: expecting indirect string");
2557a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         fnname = ML_(cur_read_strdup)( cts.u.cur,
2558a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                                        "get_inlFnName.1" );
2559a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ret = ML_(addStr)(cc->di, fnname, -1);
2560a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ML_(dinfo_free) (fnname);
25610ff164112b6a398fa7e60dffed3c2b6dcf9dda25philippe         break; /* Name found, get out of the loop, as this has priority over
25620ff164112b6a398fa7e60dffed3c2b6dcf9dda25philippe                 DW_AT_specification. */
25630ff164112b6a398fa7e60dffed3c2b6dcf9dda25philippe      }
25640ff164112b6a398fa7e60dffed3c2b6dcf9dda25philippe      if (attr == DW_AT_specification) {
25650ff164112b6a398fa7e60dffed3c2b6dcf9dda25philippe         if (cts.szB == 0)
25660ff164112b6a398fa7e60dffed3c2b6dcf9dda25philippe            cc->barf("get_inlFnName: AT specification missing");
25670ff164112b6a398fa7e60dffed3c2b6dcf9dda25philippe         /* hoping that there is no loop */
25680ff164112b6a398fa7e60dffed3c2b6dcf9dda25philippe         ret = get_inlFnName (cts.u.val, cc, td3);
25690ff164112b6a398fa7e60dffed3c2b6dcf9dda25philippe         /*
25700ff164112b6a398fa7e60dffed3c2b6dcf9dda25philippe            Unclear if having both DW_AT_specification and DW_AT_name is
25710ff164112b6a398fa7e60dffed3c2b6dcf9dda25philippe            possible but in any case, we do not break here.
25720ff164112b6a398fa7e60dffed3c2b6dcf9dda25philippe            If we find later on a DW_AT_name, it will override the name found
25730ff164112b6a398fa7e60dffed3c2b6dcf9dda25philippe            in the DW_AT_specification.*/
2574a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
2575b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2576a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2577a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (ret)
2578a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      return ret;
25790ff164112b6a398fa7e60dffed3c2b6dcf9dda25philippe   else {
25800ff164112b6a398fa7e60dffed3c2b6dcf9dda25philippe      TRACE_D3("AbsOriFnNameNotFound");
2581a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      return ML_(addStr)(cc->di, "AbsOriFnNameNotFound", -1);
25820ff164112b6a398fa7e60dffed3c2b6dcf9dda25philippe   }
2583a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe}
2584a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2585a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe/* Returns True if the (possibly) childrens of the current DIE are interesting
2586a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   to parse. Returns False otherwise.
2587a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   If the current DIE has a sibling, the non interesting children can
2588a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   maybe be skipped (if the DIE has a DW_AT_sibling).  */
2589a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe__attribute__((noinline))
2590a0a73939b0398b6608fd6dbde49820ce6530d12cphilippestatic Bool parse_inl_DIE (
2591a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   /*MOD*/D3InlParser* parser,
2592a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   DW_TAG dtag,
2593a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UWord posn,
2594a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Int level,
2595a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Cursor* c_die,
2596a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   g_abbv *abbv,
2597a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   CUConst* cc,
2598a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Bool td3
2599a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe)
2600a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe{
2601a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   FormContents cts;
2602a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UInt nf_i;
2603a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2604a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UWord saved_die_c_offset  = get_position_of_Cursor( c_die );
2605a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2606a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   /* Get info about DW_TAG_compile_unit and DW_TAG_partial_unit 'which
2607a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      in theory could also contain inlined fn calls).  */
2608a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (dtag == DW_TAG_compile_unit || dtag == DW_TAG_partial_unit) {
2609a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Bool have_lo    = False;
2610a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Addr ip_lo    = 0;
2611666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      HChar *compdir = NULL;
2612a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2613a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      nf_i = 0;
2614a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      while (True) {
2615a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
2616a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
2617a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         nf_i++;
2618a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == 0 && form == 0) break;
2619a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
2620a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == DW_AT_low_pc && cts.szB > 0) {
2621a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            ip_lo   = cts.u.val;
2622a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            have_lo = True;
2623a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2624666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         if (attr == DW_AT_comp_dir) {
2625666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            if (cts.szB >= 0)
2626666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe               cc->barf("parse_inl_DIE compdir: expecting indirect string");
2627666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            HChar *str = ML_(cur_read_strdup)( cts.u.cur,
2628666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                                               "parse_inl_DIE.compdir" );
2629666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            compdir = ML_(addStr)(cc->di, str, -1);
2630666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            ML_(dinfo_free) (str);
2631666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe         }
2632a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == DW_AT_stmt_list && cts.szB > 0) {
2633666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            read_filename_table( parser->fndn_ix_Table, compdir,
2634666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                                 cc, cts.u.val, td3 );
2635a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2636d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe         if (attr == DW_AT_sibling && cts.szB > 0) {
2637d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe            parser->sibling = cts.u.val;
2638d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe         }
2639a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
2640a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (level == 0)
2641a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         setup_cu_svma (cc, have_lo, ip_lo, td3);
2642a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
2643a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2644a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (dtag == DW_TAG_inlined_subroutine) {
2645a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Bool   have_lo    = False;
2646a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Bool   have_hi1   = False;
2647a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Bool   have_range = False;
2648a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Bool   hiIsRelative = False;
2649a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Addr   ip_lo      = 0;
2650a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Addr   ip_hi1     = 0;
2651a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Addr   rangeoff   = 0;
2652666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      UInt   caller_fndn_ix = 0;
2653a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Int caller_lineno = 0;
2654a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Int inlinedfn_abstract_origin = 0;
2655a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2656a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      nf_i = 0;
2657a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      while (True) {
2658a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
2659a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
2660a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         nf_i++;
2661a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == 0 && form == 0) break;
2662a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
2663a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == DW_AT_call_file && cts.szB > 0) {
2664a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            Int ftabIx = (Int)cts.u.val;
2665a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (ftabIx >= 1
2666666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                && ftabIx < VG_(sizeXA)( parser->fndn_ix_Table )) {
2667666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe               caller_fndn_ix = *(UInt*)
2668666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                          VG_(indexXA)( parser->fndn_ix_Table, ftabIx );
2669a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            }
2670666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            if (0) VG_(printf)("XXX caller_fndn_ix = %d %s\n", caller_fndn_ix,
2671666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                               ML_(fndn_ix2filename) (cc->di, caller_fndn_ix));
2672a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2673a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == DW_AT_call_line && cts.szB > 0) {
2674a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            caller_lineno = cts.u.val;
2675a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2676a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2677a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == DW_AT_abstract_origin  && cts.szB > 0) {
2678a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            inlinedfn_abstract_origin = cts.u.val;
2679a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2680a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2681a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == DW_AT_low_pc && cts.szB > 0) {
2682a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            ip_lo   = cts.u.val;
2683a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            have_lo = True;
2684a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2685a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == DW_AT_high_pc && cts.szB > 0) {
2686a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            ip_hi1   = cts.u.val;
2687a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            have_hi1 = True;
2688a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (form != DW_FORM_addr)
2689a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               hiIsRelative = True;
2690a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2691a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (attr == DW_AT_ranges && cts.szB > 0) {
2692a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            rangeoff   = cts.u.val;
2693a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            have_range = True;
2694a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2695d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe         if (attr == DW_AT_sibling && cts.szB > 0) {
2696d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe            parser->sibling = cts.u.val;
2697d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe         }
2698a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
2699a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (have_lo && have_hi1 && hiIsRelative)
2700a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ip_hi1 += ip_lo;
2701a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Do we have something that looks sane? */
2702a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (dtag == DW_TAG_inlined_subroutine
2703a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe          && (!have_lo) && (!have_hi1) && (!have_range)) {
2704a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* Seems strange. How can an inlined subroutine have
2705a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            no code ? */
2706a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         goto_bad_DIE;
2707a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      } else
2708a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (have_lo && have_hi1 && (!have_range)) {
2709a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* This inlined call is just a single address range. */
2710a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (ip_lo < ip_hi1) {
2711e2d41dc65a214f6950f42d0b02cd9cc2d932d927philippe            /* Apply text debug biasing */
2712e2d41dc65a214f6950f42d0b02cd9cc2d932d927philippe            ip_lo += cc->di->text_debug_bias;
2713e2d41dc65a214f6950f42d0b02cd9cc2d932d927philippe            ip_hi1 += cc->di->text_debug_bias;
2714a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            ML_(addInlInfo) (cc->di,
2715a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             ip_lo, ip_hi1,
2716a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             get_inlFnName (inlinedfn_abstract_origin, cc, td3),
2717666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                             caller_fndn_ix,
2718a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             caller_lineno, level);
2719a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2720a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      } else if (have_range) {
2721a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* This inlined call is several address ranges. */
2722a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         XArray *ranges;
2723a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         Word j;
2724a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         HChar *inlfnname = get_inlFnName (inlinedfn_abstract_origin, cc, td3);
2725a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
27268b662d50e99428ea6b76d44a80ffaaf73eb51584philippe         /* Ranges are biased for the inline info using the same logic
27278b662d50e99428ea6b76d44a80ffaaf73eb51584philippe            as what is used for biasing ranges for the var info, for which
27288b662d50e99428ea6b76d44a80ffaaf73eb51584philippe            ranges are read using cc->cu_svma (see parse_var_DIE).
27298b662d50e99428ea6b76d44a80ffaaf73eb51584philippe            Then text_debug_bias is added when a (non global) var
27308b662d50e99428ea6b76d44a80ffaaf73eb51584philippe            is recorded (see just before the call to ML_(addVar)) */
2731a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ranges = get_range_list( cc, td3,
2732a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                                  rangeoff, cc->cu_svma );
2733a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         for (j = 0; j < VG_(sizeXA)( ranges ); j++) {
2734a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            AddrRange* range = (AddrRange*) VG_(indexXA)( ranges, j );
2735a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            ML_(addInlInfo) (cc->di,
27368b662d50e99428ea6b76d44a80ffaaf73eb51584philippe                             range->aMin   + cc->di->text_debug_bias,
27378b662d50e99428ea6b76d44a80ffaaf73eb51584philippe                             range->aMax+1 + cc->di->text_debug_bias,
2738a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             // aMax+1 as range has its last bound included
2739a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             // while ML_(addInlInfo) expects last bound not
2740a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             // included.
2741a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             inlfnname,
2742666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                             caller_fndn_ix,
2743a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             caller_lineno, level);
2744a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
2745a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         VG_(deleteXA)( ranges );
2746a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      } else
2747a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         goto_bad_DIE;
2748a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
2749a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2750a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   // Only recursively parse the (possible) children for the DIE which
2751a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   // might maybe contain a DW_TAG_inlined_subroutine:
2752a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   return dtag == DW_TAG_lexical_block || dtag == DW_TAG_subprogram
2753a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      || dtag == DW_TAG_inlined_subroutine
2754a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      || dtag == DW_TAG_compile_unit || dtag == DW_TAG_partial_unit;
2755a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
2756a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe  bad_DIE:
2757896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe   dump_bad_die_and_barf("parse_inl_DIE", dtag, posn, level,
2758a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                         c_die, saved_die_c_offset,
2759a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                         abbv,
2760a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                         cc);
2761b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
2762b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2763b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2764b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2765b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
2766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
2767b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Parsing of type-related DIEs                         ---*/
2768b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
2769b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
2770b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2771b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#define N_D3_TYPE_STACK 16
2772b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2773b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjtypedef
2774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct {
27752acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      /* What source language?  'A'=Ada83/95,
27762acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj                                'C'=C/C++,
27772acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj                                'F'=Fortran,
27782acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj                                '?'=other
2779b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         Established once per compilation unit. */
2780b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar language;
2781b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* A stack of types which are currently under construction */
2782b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int   sp; /* [sp] is innermost active entry; sp==-1 for empty
2783b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   stack */
27849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* Note that the TyEnts in qparentE are temporary copies of the
27859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ones accumulating in the main tyent array.  So it is not safe
27869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         to free up anything on them when popping them off the stack
27879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         (iow, it isn't safe to use TyEnt__make_EMPTY on them).  Just
27889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         memset them to zero when done. */
27899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TyEnt qparentE[N_D3_TYPE_STACK]; /* parent TyEnts */
2790b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int   qlevel[N_D3_TYPE_STACK];
2791b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2793b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   D3TypeParser;
2794b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
27956bd9dc18c043927c1196caba20a327238a179c42florianstatic void typestack_show ( D3TypeParser* parser, const HChar* str ) {
2796b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Word i;
2797b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(printf)("  typestack (%s) {\n", str);
2798b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for (i = 0; i <= parser->sp; i++) {
2799b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(printf)("    [%ld] (level %d): ", i, parser->qlevel[i]);
28009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      ML_(pp_TyEnt)( &parser->qparentE[i] );
2801b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      VG_(printf)("\n");
2802b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2803b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   VG_(printf)("  }\n");
2804b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2805b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2806b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Remove from the stack, all entries with .level > 'level' */
2807b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic
2808b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid typestack_preen ( D3TypeParser* parser, Bool td3, Int level )
2809b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
2810b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Bool changed = False;
2811b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp < N_D3_TYPE_STACK);
2812b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
2813b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(parser->sp >= -1);
2814b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (parser->sp == -1) break;
2815b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (parser->qlevel[parser->sp] <= level) break;
2816b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (0)
2817b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("BBBBAAAA typestack_pop [newsp=%d]\n", parser->sp-1);
28189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
28199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&parser->qparentE[parser->sp], 0, sizeof(TyEnt));
28209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      parser->qparentE[parser->sp].cuOff = D3_INVALID_CUOFF;
28219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      parser->qparentE[parser->sp].tag = Te_EMPTY;
28229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      parser->qlevel[parser->sp] = 0;
2823b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parser->sp--;
2824b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      changed = True;
2825b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2826b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (changed && td3)
2827b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      typestack_show( parser, "after preen" );
2828b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2829b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic Bool typestack_is_empty ( D3TypeParser* parser ) {
2831b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp >= -1 && parser->sp < N_D3_TYPE_STACK);
2832b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return parser->sp == -1;
2833b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2834b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2835b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjstatic void typestack_push ( CUConst* cc,
2836b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             D3TypeParser* parser,
2837b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             Bool td3,
28389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                             TyEnt* parentE, Int level ) {
2839b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (0)
28409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TRACE_D3("BBBBAAAA typestack_push[newsp=%d]: %d  %05lx\n",
28419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            parser->sp+1, level, parentE->cuOff);
2842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* First we need to zap everything >= 'level', as we are about to
2844b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      replace any previous entry at 'level', so .. */
2845b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   typestack_preen(parser, /*td3*/False, level-1);
2846b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2847b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp >= -1);
2848b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->sp < N_D3_TYPE_STACK);
2849b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (parser->sp == N_D3_TYPE_STACK-1)
2850b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("typestack_push: N_D3_TYPE_STACK is too low; "
2851b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               "increase and recompile");
2852b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (parser->sp >= 0)
2853b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(parser->qlevel[parser->sp] < level);
2854b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->sp++;
28559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(parser->qparentE[parser->sp].tag == Te_EMPTY);
2856b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(parser->qlevel[parser->sp]  == 0);
28579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(parentE);
28589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(ML_(TyEnt__is_type)(parentE));
28599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(parentE->cuOff != D3_INVALID_CUOFF);
28609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   parser->qparentE[parser->sp] = *parentE;
2861b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   parser->qlevel[parser->sp]  = level;
2862e0bd5910153720d5d15697db8063d0d4caa59d8fphilippe   if (TD3)
2863b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      typestack_show( parser, "after push" );
2864b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
2865b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
28662acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj/* True if the subrange type being parsed gives the bounds of an array. */
28672acc87cac77cedb3884e9e3a5188bac6edda5aeesewardjstatic Bool subrange_type_denotes_array_bounds ( D3TypeParser* parser,
28682acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj                                                 DW_TAG dtag ) {
28692acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   vg_assert(dtag == DW_TAG_subrange_type);
28702acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   /* For most languages, a subrange_type dtag always gives the
28712acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      bounds of an array.
28722acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      For Ada, there are additional conditions as a subrange_type
28732acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      is also used for other purposes. */
28742acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   if (parser->language != 'A')
28752acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      /* not Ada, so it definitely denotes an array bound. */
28762acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      return True;
28772acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   else
28782acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      /* Extra constraints for Ada: it only denotes an array bound if .. */
28792acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      return (! typestack_is_empty(parser)
28802acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj              && parser->qparentE[parser->sp].tag == Te_TyArray);
28812acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj}
2882b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2883b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Parse a type-related DIE.  'parser' holds the current parser state.
2884b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   'admin' is where the completed types are dumped.  'dtag' is the tag
2885b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   for this DIE.  'c_die' points to the start of the data fields (FORM
2886746e97e7098def65d59c79d5d661f9a757a837cdphilippe   stuff) for the DIE.  abbv is the parsed abbreviation which describe
2887746e97e7098def65d59c79d5d661f9a757a837cdphilippe   the DIE.
2888b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2889b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   We may find the DIE uninteresting, in which case we should ignore
2890b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   it.
28919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
28929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   What happens: the DIE is examined.  If uninteresting, it is ignored.
28939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Otherwise, the DIE gives rise to two things:
28949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
28959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   (1) the offset of this DIE in the CU -- the cuOffset, a UWord
28969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   (2) a TyAdmin structure, which holds the type, or related stuff
28979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
28989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   (2) is added at the end of 'tyadmins', at some index, say 'i'.
28999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
29009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   A pair (cuOffset, i) is added to 'tydict'.
29019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
29029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Hence 'tyadmins' holds the actual type entities, and 'tydict' holds
29039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   a mapping from cuOffset to the index of the corresponding entry in
29049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   'tyadmin'.
29059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
29069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   When resolving a cuOffset to a TyAdmin, first look up the cuOffset
29079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   in the tydict (by binary search).  This gives an index into
29089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   tyadmins, and the required entity lives in tyadmins at that index.
2909b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj*/
2910b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj__attribute__((noinline))
29119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents,
2912b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             /*MOD*/D3TypeParser* parser,
2913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             DW_TAG dtag,
2914b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             UWord posn,
2915b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             Int level,
2916b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             Cursor* c_die,
2917746e97e7098def65d59c79d5d661f9a757a837cdphilippe                             g_abbv *abbv,
2918b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             CUConst* cc,
2919b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                             Bool td3 )
2920b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
29215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   FormContents cts;
2922a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UInt nf_i;
29239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEnt typeE;
29249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEnt atomE;
29259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEnt fieldE;
29269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEnt boundE;
2927b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2928b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UWord saved_die_c_offset  = get_position_of_Cursor( c_die );
2929b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
29309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(memset)( &typeE,  0xAA, sizeof(typeE) );
29319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(memset)( &atomE,  0xAA, sizeof(atomE) );
29329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(memset)( &fieldE, 0xAA, sizeof(fieldE) );
29339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(memset)( &boundE, 0xAA, sizeof(boundE) );
29349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
2935b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* If we've returned to a level at or above any previously noted
2936b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parent, un-note it, so we don't believe we're still collecting
2937b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      its children. */
2938b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   typestack_preen( parser, td3, level-1 );
2939b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2940f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   if (dtag == DW_TAG_compile_unit
2941f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj       || dtag == DW_TAG_type_unit
2942f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj       || dtag == DW_TAG_partial_unit) {
2943b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* See if we can find DW_AT_language, since it is important for
2944b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         establishing array bounds (see DW_TAG_subrange_type below in
2945b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         this fn) */
2946746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
2947b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2948746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
2949746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
2950746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
2951b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
29525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
2953b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr != DW_AT_language)
2954b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            continue;
29555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (cts.szB <= 0)
29565c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe           goto_bad_DIE;
29575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         switch (cts.u.val) {
2958b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_C89: case DW_LANG_C:
2959b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_C_plus_plus: case DW_LANG_ObjC:
2960b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_ObjC_plus_plus: case DW_LANG_UPC:
2961fba428cd266b8a39db641c5fd9523daa8939bed0tom            case DW_LANG_Upc: case DW_LANG_C99:
2962b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               parser->language = 'C'; break;
2963b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_Fortran77: case DW_LANG_Fortran90:
2964b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_Fortran95:
2965b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               parser->language = 'F'; break;
29662acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj            case DW_LANG_Ada83: case DW_LANG_Ada95:
29672acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj               parser->language = 'A'; break;
29682acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj            case DW_LANG_Cobol74:
2969b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_Cobol85: case DW_LANG_Pascal83:
2970b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_Modula2: case DW_LANG_Java:
29712acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj            case DW_LANG_PLI:
2972fba428cd266b8a39db641c5fd9523daa8939bed0tom            case DW_LANG_D: case DW_LANG_Python:
2973b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            case DW_LANG_Mips_Assembler:
2974b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               parser->language = '?'; break;
2975b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            default:
29765c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe               goto_bad_DIE;
2977b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
2978b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
2979b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
2980b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
2981b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_base_type) {
2982b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* We can pick up a new base type any time. */
29839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
29849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = D3_INVALID_CUOFF;
29859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyBase;
2986746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
2987b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
2988746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
2989746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
2990746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
2991b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
29925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
29935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
29949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            typeE.Te.TyBase.name
29955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = ML_(cur_read_strdup)( cts.u.cur,
29965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       "di.readdwarf3.ptD.base_type.1" );
2997b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
29985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_byte_size && cts.szB > 0) {
29995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyBase.szB = cts.u.val;
3000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
30015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_encoding && cts.szB > 0) {
30025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            switch (cts.u.val) {
3003b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               case DW_ATE_unsigned: case DW_ATE_unsigned_char:
300450c5093772c2b23fd0897d3590dcfaec1c92ac83tom               case DW_ATE_UTF: /* since DWARF4, e.g. char16_t from C++ */
3005b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               case DW_ATE_boolean:/* FIXME - is this correct? */
30065db15403e889d4db339b342bc2a824ef0bfaa654sewardj               case DW_ATE_unsigned_fixed:
30079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                  typeE.Te.TyBase.enc = 'U'; break;
3008b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               case DW_ATE_signed: case DW_ATE_signed_char:
30095db15403e889d4db339b342bc2a824ef0bfaa654sewardj               case DW_ATE_signed_fixed:
30109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                  typeE.Te.TyBase.enc = 'S'; break;
3011b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               case DW_ATE_float:
30129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                  typeE.Te.TyBase.enc = 'F'; break;
3013b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               case DW_ATE_complex_float:
30149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                  typeE.Te.TyBase.enc = 'C'; break;
3015b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               default:
30165c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe                  goto_bad_DIE;
3017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            }
3018b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3019b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3020b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3021b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Invent a name if it doesn't have one.  gcc-4.3
3022b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         -ftree-vectorize is observed to emit nameless base types. */
30239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (!typeE.Te.TyBase.name)
30249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         typeE.Te.TyBase.name
30259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = ML_(dinfo_strdup)( "di.readdwarf3.ptD.base_type.2",
30269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                 "<anon_base_type>" );
3027b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3028b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
3029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (/* must have a name */
30309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj          typeE.Te.TyBase.name == NULL
3031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          /* and a plausible size.  Yes, really 32: "complex long
3032b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             double" apparently has size=32 */
30339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj          || typeE.Te.TyBase.szB < 0 || typeE.Te.TyBase.szB > 32
3034b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj          /* and a plausible encoding */
30359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj          || (typeE.Te.TyBase.enc != 'U'
30369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj              && typeE.Te.TyBase.enc != 'S'
30379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj              && typeE.Te.TyBase.enc != 'F'
30389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj              && typeE.Te.TyBase.enc != 'C'))
30395c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
3040b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Last minute hack: if we see this
3041b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         <1><515>: DW_TAG_base_type
3042b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_byte_size   : 0
3043b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_encoding    : 5
3044b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj             DW_AT_name        : void
3045b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         convert it into a real Void type. */
30469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (typeE.Te.TyBase.szB == 0
30479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj          && 0 == VG_(strcmp)("void", typeE.Te.TyBase.name)) {
30489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ML_(TyEnt__make_EMPTY)(&typeE);
30499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         typeE.tag = Te_TyVoid;
30509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         typeE.Te.TyVoid.isFake = False; /* it's a real one! */
3051b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
30529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
3053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      goto acquire_Type;
3054b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3055b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
30560e947cfedebda6da2e84fb61af431db5cf1275fcbart   /*
30570e947cfedebda6da2e84fb61af431db5cf1275fcbart    * An example of DW_TAG_rvalue_reference_type:
30580e947cfedebda6da2e84fb61af431db5cf1275fcbart    *
30590e947cfedebda6da2e84fb61af431db5cf1275fcbart    * $ readelf --debug-dump /usr/lib/debug/usr/lib/libstdc++.so.6.0.16.debug
30600e947cfedebda6da2e84fb61af431db5cf1275fcbart    *  <1><1014>: Abbrev Number: 55 (DW_TAG_rvalue_reference_type)
30610e947cfedebda6da2e84fb61af431db5cf1275fcbart    *     <1015>   DW_AT_byte_size   : 4
30620e947cfedebda6da2e84fb61af431db5cf1275fcbart    *     <1016>   DW_AT_type        : <0xe52>
30630e947cfedebda6da2e84fb61af431db5cf1275fcbart    */
3064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_pointer_type || dtag == DW_TAG_reference_type
30650e947cfedebda6da2e84fb61af431db5cf1275fcbart       || dtag == DW_TAG_ptr_to_member_type
30660e947cfedebda6da2e84fb61af431db5cf1275fcbart       || dtag == DW_TAG_rvalue_reference_type) {
3067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* This seems legit for _pointer_type and _reference_type.  I
3068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         don't know if rolling _ptr_to_member_type in here really is
3069b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         legit, but it's better than not handling it at all. */
30709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
30719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = D3_INVALID_CUOFF;
30720e947cfedebda6da2e84fb61af431db5cf1275fcbart      switch (dtag) {
30730e947cfedebda6da2e84fb61af431db5cf1275fcbart      case DW_TAG_pointer_type:
30740e947cfedebda6da2e84fb61af431db5cf1275fcbart         typeE.tag = Te_TyPtr;
30750e947cfedebda6da2e84fb61af431db5cf1275fcbart         break;
30760e947cfedebda6da2e84fb61af431db5cf1275fcbart      case DW_TAG_reference_type:
30770e947cfedebda6da2e84fb61af431db5cf1275fcbart         typeE.tag = Te_TyRef;
30780e947cfedebda6da2e84fb61af431db5cf1275fcbart         break;
30790e947cfedebda6da2e84fb61af431db5cf1275fcbart      case DW_TAG_ptr_to_member_type:
30800e947cfedebda6da2e84fb61af431db5cf1275fcbart         typeE.tag = Te_TyPtrMbr;
30810e947cfedebda6da2e84fb61af431db5cf1275fcbart         break;
30820e947cfedebda6da2e84fb61af431db5cf1275fcbart      case DW_TAG_rvalue_reference_type:
30830e947cfedebda6da2e84fb61af431db5cf1275fcbart         typeE.tag = Te_TyRvalRef;
30840e947cfedebda6da2e84fb61af431db5cf1275fcbart         break;
30850e947cfedebda6da2e84fb61af431db5cf1275fcbart      default:
30860e947cfedebda6da2e84fb61af431db5cf1275fcbart         vg_assert(False);
30870e947cfedebda6da2e84fb61af431db5cf1275fcbart      }
3088b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* target type defaults to void */
30899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyPorR.typeR = D3_FAKEVOID_CUOFF;
30900e947cfedebda6da2e84fb61af431db5cf1275fcbart      /* These four type kinds don't *have* to specify their size, in
309131452303b095a76295b08096b2840276db808b81sewardj         which case we assume it's a machine word.  But if they do
309231452303b095a76295b08096b2840276db808b81sewardj         specify it, it must be a machine word :-)  This probably
309331452303b095a76295b08096b2840276db808b81sewardj         assumes that the word size of the Dwarf3 we're reading is the
309431452303b095a76295b08096b2840276db808b81sewardj         same size as that on the machine.  gcc appears to give a size
309531452303b095a76295b08096b2840276db808b81sewardj         whereas icc9 doesn't. */
309631452303b095a76295b08096b2840276db808b81sewardj      typeE.Te.TyPorR.szB = sizeof(UWord);
3097746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
3098b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
3099746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
3100746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
3101746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
3102b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
31035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
31045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_byte_size && cts.szB > 0) {
31055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyPorR.szB = cts.u.val;
3106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
31075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_type && cts.szB > 0) {
31085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyPorR.typeR
31095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = cook_die_using_form( cc, (UWord)cts.u.val, form );
3110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
311331452303b095a76295b08096b2840276db808b81sewardj      if (typeE.Te.TyPorR.szB != sizeof(UWord))
31145c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
3115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      else
3116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto acquire_Type;
3117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_enumeration_type) {
3120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Create a new Type to hold the results. */
31219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
31229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = posn;
31239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyEnum;
31249d82d0f293c83ff2b8c3ab07065d8454059452bemjw      Bool is_decl = False;
31259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyEnum.atomRs
31269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ptD.enum_type.1",
31279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                       ML_(dinfo_free),
31289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                       sizeof(UWord) );
3129746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i=0;
3130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
3131746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
3132746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
3133746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
3134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
31355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
31365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
31379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            typeE.Te.TyEnum.name
31385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = ML_(cur_read_strdup)( cts.u.cur,
31395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       "di.readdwarf3.pTD.enum_type.2" );
3140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
31415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_byte_size && cts.szB > 0) {
31425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyEnum.szB = cts.u.val;
3143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
31449d82d0f293c83ff2b8c3ab07065d8454059452bemjw         if (attr == DW_AT_declaration) {
31459d82d0f293c83ff2b8c3ab07065d8454059452bemjw            is_decl = True;
31469d82d0f293c83ff2b8c3ab07065d8454059452bemjw         }
3147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
31486ece231961274337eb8303aba3ac5247fc7d1ef9sewardj
31496ece231961274337eb8303aba3ac5247fc7d1ef9sewardj      if (!typeE.Te.TyEnum.name)
31506ece231961274337eb8303aba3ac5247fc7d1ef9sewardj         typeE.Te.TyEnum.name
31516ece231961274337eb8303aba3ac5247fc7d1ef9sewardj            = ML_(dinfo_strdup)( "di.readdwarf3.pTD.enum_type.3",
31526ece231961274337eb8303aba3ac5247fc7d1ef9sewardj                                 "<anon_enum_type>" );
31536ece231961274337eb8303aba3ac5247fc7d1ef9sewardj
3154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
31552acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      if (typeE.Te.TyEnum.szB == 0
31562acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj          /* we must know the size */
31572acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj          /* but not for Ada, which uses such dummy
31589d82d0f293c83ff2b8c3ab07065d8454059452bemjw             enumerations as helper for gdb ada mode.
31599d82d0f293c83ff2b8c3ab07065d8454059452bemjw             Also GCC allows incomplete enums as GNU extension.
31609d82d0f293c83ff2b8c3ab07065d8454059452bemjw             http://gcc.gnu.org/onlinedocs/gcc/Incomplete-Enums.html
31619d82d0f293c83ff2b8c3ab07065d8454059452bemjw             These are marked as DW_AT_declaration and won't have
31629d82d0f293c83ff2b8c3ab07065d8454059452bemjw             a size. They can only be used in declaration or as
31639d82d0f293c83ff2b8c3ab07065d8454059452bemjw             pointer types.  You can't allocate variables or storage
31649d82d0f293c83ff2b8c3ab07065d8454059452bemjw             using such an enum type. (Also GCC seems to have a bug
31659d82d0f293c83ff2b8c3ab07065d8454059452bemjw             that will put such an enumeration_type into a .debug_types
31669d82d0f293c83ff2b8c3ab07065d8454059452bemjw             unit which should only contain complete types.) */
31679d82d0f293c83ff2b8c3ab07065d8454059452bemjw          && (parser->language != 'A' && !is_decl)) {
31685c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
3169d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      }
3170d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
3171b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* On't stack! */
31729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typestack_push( cc, parser, td3, &typeE, level );
3173b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      goto acquire_Type;
3174b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3175b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3176f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj   /* gcc (GCC) 4.4.0 20081017 (experimental) occasionally produces
3177f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      DW_TAG_enumerator with only a DW_AT_name but no
3178f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      DW_AT_const_value.  This is in violation of the Dwarf3 standard,
3179f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      and appears to be a new "feature" of gcc - versions 4.3.x and
3180f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      earlier do not appear to do this.  So accept DW_TAG_enumerator
3181f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      which only have a name but no value.  An example:
3182f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj
3183f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      <1><180>: Abbrev Number: 6 (DW_TAG_enumeration_type)
3184f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <181>   DW_AT_name        : (indirect string, offset: 0xda70):
3185f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj                                     QtMsgType
3186f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <185>   DW_AT_byte_size   : 4
3187f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <186>   DW_AT_decl_file   : 14
3188f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <187>   DW_AT_decl_line   : 1480
3189f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <189>   DW_AT_sibling     : <0x1a7>
3190f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      <2><18d>: Abbrev Number: 7 (DW_TAG_enumerator)
3191f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <18e>   DW_AT_name        : (indirect string, offset: 0x9e18):
3192f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj                                     QtDebugMsg
3193f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      <2><192>: Abbrev Number: 7 (DW_TAG_enumerator)
3194f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <193>   DW_AT_name        : (indirect string, offset: 0x1505f):
3195f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj                                     QtWarningMsg
3196f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      <2><197>: Abbrev Number: 7 (DW_TAG_enumerator)
3197f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <198>   DW_AT_name        : (indirect string, offset: 0x16f4a):
3198f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj                                     QtCriticalMsg
3199f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      <2><19c>: Abbrev Number: 7 (DW_TAG_enumerator)
3200f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <19d>   DW_AT_name        : (indirect string, offset: 0x156dd):
3201f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj                                     QtFatalMsg
3202f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      <2><1a1>: Abbrev Number: 7 (DW_TAG_enumerator)
3203f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj         <1a2>   DW_AT_name        : (indirect string, offset: 0x13660):
3204f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj                                     QtSystemMsg
3205f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj   */
3206b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_enumerator) {
32079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)( &atomE, 0, sizeof(atomE) );
32089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      atomE.cuOff = posn;
32099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      atomE.tag   = Te_Atom;
3210746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
3211b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
3212746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
3213746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
3214746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
3215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
32165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
32175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
32189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            atomE.Te.Atom.name
32195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj              = ML_(cur_read_strdup)( cts.u.cur,
32205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                      "di.readdwarf3.pTD.enumerator.1" );
3221b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
32225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_const_value && cts.szB > 0) {
32235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            atomE.Te.Atom.value      = cts.u.val;
3224f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj            atomE.Te.Atom.valueKnown = True;
3225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3226b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3227b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
3228f3aaa337f0bd3084b339cdcff58ef6fef25bf15fsewardj      if (atomE.Te.Atom.name == NULL)
32295c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
3230b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have a plausible parent? */
32315c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe      if (typestack_is_empty(parser)) goto_bad_DIE;
32329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
32339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(parser->qparentE[parser->sp].cuOff != D3_INVALID_CUOFF);
32345c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe      if (level != parser->qlevel[parser->sp]+1) goto_bad_DIE;
32355c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe      if (parser->qparentE[parser->sp].tag != Te_TyEnum) goto_bad_DIE;
3236b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Record this child in the parent */
32379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(parser->qparentE[parser->sp].Te.TyEnum.atomRs);
32389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(addToXA)( parser->qparentE[parser->sp].Te.TyEnum.atomRs,
32399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                    &atomE );
3240b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* And record the child itself */
3241b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      goto acquire_Atom;
3242b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
32446a3a28409187ca6813b228afaf2af288c1fcd73dsewardj   /* Treat DW_TAG_class_type as if it was a DW_TAG_structure_type.  I
32456a3a28409187ca6813b228afaf2af288c1fcd73dsewardj      don't know if this is correct, but it at least makes this reader
32466a3a28409187ca6813b228afaf2af288c1fcd73dsewardj      usable for gcc-4.3 produced Dwarf3. */
32476a3a28409187ca6813b228afaf2af288c1fcd73dsewardj   if (dtag == DW_TAG_structure_type || dtag == DW_TAG_class_type
32486a3a28409187ca6813b228afaf2af288c1fcd73dsewardj       || dtag == DW_TAG_union_type) {
3249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_szB = False;
3250b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool is_decl  = False;
3251b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool is_spec  = False;
3252b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Create a new Type to hold the results. */
32539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
32549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = posn;
32559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyStOrUn;
32569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyStOrUn.name = NULL;
32570abc4193f82294904ed9478fa80394224c03fcc0dejanj      typeE.Te.TyStOrUn.typeR = D3_INVALID_CUOFF;
32589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyStOrUn.fieldRs
32599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.pTD.struct_type.1",
32609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                       ML_(dinfo_free),
32619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                       sizeof(UWord) );
32629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyStOrUn.complete = True;
32639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyStOrUn.isStruct = dtag == DW_TAG_structure_type
32649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                   || dtag == DW_TAG_class_type;
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_name && cts.szB < 0) {
32739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            typeE.Te.TyStOrUn.name
32745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = ML_(cur_read_strdup)( cts.u.cur,
32755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       "di.readdwarf3.ptD.struct_type.2" );
3276b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
32775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_byte_size && cts.szB >= 0) {
32785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyStOrUn.szB = cts.u.val;
3279b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_szB = True;
3280b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
32815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_declaration && cts.szB > 0 && cts.u.val > 0) {
3282b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            is_decl = True;
3283b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
32845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_specification && cts.szB > 0 && cts.u.val > 0) {
3285b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            is_spec = True;
3286b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
32870abc4193f82294904ed9478fa80394224c03fcc0dejanj         if (attr == DW_AT_signature && form == DW_FORM_ref_sig8
32880abc4193f82294904ed9478fa80394224c03fcc0dejanj             && cts.szB > 0) {
32890abc4193f82294904ed9478fa80394224c03fcc0dejanj            have_szB = True;
32900abc4193f82294904ed9478fa80394224c03fcc0dejanj            typeE.Te.TyStOrUn.szB = 8;
32910abc4193f82294904ed9478fa80394224c03fcc0dejanj            typeE.Te.TyStOrUn.typeR
32920abc4193f82294904ed9478fa80394224c03fcc0dejanj               = cook_die_using_form( cc, (UWord)cts.u.val, form );
32930abc4193f82294904ed9478fa80394224c03fcc0dejanj         }
3294b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane? */
3296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (is_decl && (!is_spec)) {
3297b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* It's a DW_AT_declaration.  We require the name but
3298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            nothing else. */
329900888885d88a5264711c22074cfd3462020cbee6sewardj         /* JRS 2012-06-28: following discussion w/ tromey, if the the
330000888885d88a5264711c22074cfd3462020cbee6sewardj            type doesn't have name, just make one up, and accept it.
330100888885d88a5264711c22074cfd3462020cbee6sewardj            It might be referred to by other DIEs, so ignoring it
330200888885d88a5264711c22074cfd3462020cbee6sewardj            doesn't seem like a safe option. */
33039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (typeE.Te.TyStOrUn.name == NULL)
330400888885d88a5264711c22074cfd3462020cbee6sewardj            typeE.Te.TyStOrUn.name
330500888885d88a5264711c22074cfd3462020cbee6sewardj               = ML_(dinfo_strdup)( "di.readdwarf3.ptD.struct_type.3",
330600888885d88a5264711c22074cfd3462020cbee6sewardj                                    "<anon_struct_type>" );
33079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         typeE.Te.TyStOrUn.complete = False;
3308b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj         /* JRS 2009 Aug 10: <possible kludge>? */
3309b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj         /* Push this tyent on the stack, even though it's incomplete.
3310b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj            It appears that gcc-4.4 on Fedora 11 will sometimes create
3311b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj            DW_TAG_member entries for it, and so we need to have a
3312b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj            plausible parent present in order for that to work.  See
3313b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj            #200029 comments 8 and 9. */
3314b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj         typestack_push( cc, parser, td3, &typeE, level );
3315b34bb1d378ba9e5b09e993ed9adbfaf151238878sewardj         /* </possible kludge> */
3316b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto acquire_Type;
3317b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3318b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if ((!is_decl) /* && (!is_spec) */) {
3319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* this is the common, ordinary case */
33205c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         /* The name can be present, or not */
33215c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         if (!have_szB) {
33225c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe            /* We must know the size.
33235c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe               But in Ada, record with discriminants might have no size.
33245c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe               But in C, VLA in the middle of a struct (gcc extension)
33255c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe               might have no size.
33265c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe               Instead, some GNAT dwarf extensions and/or dwarf entries
33275c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe               allow to calculate the struct size at runtime.
33285c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe               We cannot do that (yet?) so, the temporary kludge is to use
33295c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe               a small size. */
33305c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe            typeE.Te.TyStOrUn.szB = 1;
33315c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         }
3332b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* On't stack! */
33339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         typestack_push( cc, parser, td3, &typeE, level );
3334b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto acquire_Type;
3335b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3336b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      else {
3337b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* don't know how to handle any other variants just now */
33385c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
3339b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3340b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_member) {
3343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Acquire member entries for both DW_TAG_structure_type and
3344b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_TAG_union_type.  They differ minorly, in that struct
3345b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         members must have a DW_AT_data_member_location expression
3346b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         whereas union members must not. */
3347b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool parent_is_struct;
33489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)( &fieldE, 0, sizeof(fieldE) );
33499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      fieldE.cuOff = posn;
33509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      fieldE.tag   = Te_Field;
33519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      fieldE.Te.Field.typeR = D3_INVALID_CUOFF;
3352746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
3353b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
3354746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
3355746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
3356746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
3357b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
33585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
33595d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
33609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            fieldE.Te.Field.name
33615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = ML_(cur_read_strdup)( cts.u.cur,
33625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       "di.readdwarf3.ptD.member.1" );
3363b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
33645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_type && cts.szB > 0) {
33655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            fieldE.Te.Field.typeR
33665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = cook_die_using_form( cc, (UWord)cts.u.val, form );
3367b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
33683c9cf3442185b5891e15450d6e3058aeff6796fetom         /* There are 2 different cases for DW_AT_data_member_location.
33693c9cf3442185b5891e15450d6e3058aeff6796fetom            If it is a constant class attribute, it contains byte offset
33703c9cf3442185b5891e15450d6e3058aeff6796fetom            from the beginning of the containing entity.
33713c9cf3442185b5891e15450d6e3058aeff6796fetom            Otherwise it is a location expression.  */
33725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_data_member_location && cts.szB > 0) {
33733c9cf3442185b5891e15450d6e3058aeff6796fetom            fieldE.Te.Field.nLoc = -1;
33745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            fieldE.Te.Field.pos.offset = cts.u.val;
33755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
33765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_data_member_location && cts.szB <= 0) {
33775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            fieldE.Te.Field.nLoc = (UWord)(-cts.szB);
33783c9cf3442185b5891e15450d6e3058aeff6796fetom            fieldE.Te.Field.pos.loc
33795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = ML_(cur_read_memdup)( cts.u.cur,
33805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       (SizeT)fieldE.Te.Field.nLoc,
33815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       "di.readdwarf3.ptD.member.2" );
3382b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3383b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3384b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have a plausible parent? */
33855c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe      if (typestack_is_empty(parser)) goto_bad_DIE;
33869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
33879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(parser->qparentE[parser->sp].cuOff != D3_INVALID_CUOFF);
33885c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe      if (level != parser->qlevel[parser->sp]+1) goto_bad_DIE;
33895c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe      if (parser->qparentE[parser->sp].tag != Te_TyStOrUn) goto_bad_DIE;
3390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have something that looks sane?  If this a member of a
3391b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         struct, we must have a location expression; but if a member
3392b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         of a union that is irrelevant (D3 spec sec 5.6.6).  We ought
3393b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         to reject in the latter case, but some compilers have been
3394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         observed to emit constant-zero expressions.  So just ignore
3395b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         them. */
3396b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      parent_is_struct
33979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         = parser->qparentE[parser->sp].Te.TyStOrUn.isStruct;
33989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (!fieldE.Te.Field.name)
33999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         fieldE.Te.Field.name
34009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = ML_(dinfo_strdup)( "di.readdwarf3.ptD.member.3",
34019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                 "<anon_field>" );
34029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(fieldE.Te.Field.name);
34039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (fieldE.Te.Field.typeR == D3_INVALID_CUOFF)
34045c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
34053c9cf3442185b5891e15450d6e3058aeff6796fetom      if (fieldE.Te.Field.nLoc) {
340607de5ddba10bfebab8416a8f79c349faa62bbaa1tom         if (!parent_is_struct) {
340707de5ddba10bfebab8416a8f79c349faa62bbaa1tom            /* If this is a union type, pretend we haven't seen the data
340807de5ddba10bfebab8416a8f79c349faa62bbaa1tom               member location expression, as it is by definition
340907de5ddba10bfebab8416a8f79c349faa62bbaa1tom               redundant (it must be zero). */
34103c9cf3442185b5891e15450d6e3058aeff6796fetom            if (fieldE.Te.Field.nLoc > 0)
34113c9cf3442185b5891e15450d6e3058aeff6796fetom               ML_(dinfo_free)(fieldE.Te.Field.pos.loc);
34123c9cf3442185b5891e15450d6e3058aeff6796fetom            fieldE.Te.Field.pos.loc = NULL;
341307de5ddba10bfebab8416a8f79c349faa62bbaa1tom            fieldE.Te.Field.nLoc = 0;
341407de5ddba10bfebab8416a8f79c349faa62bbaa1tom         }
341507de5ddba10bfebab8416a8f79c349faa62bbaa1tom         /* Record this child in the parent */
341607de5ddba10bfebab8416a8f79c349faa62bbaa1tom         fieldE.Te.Field.isStruct = parent_is_struct;
341707de5ddba10bfebab8416a8f79c349faa62bbaa1tom         vg_assert(parser->qparentE[parser->sp].Te.TyStOrUn.fieldRs);
341807de5ddba10bfebab8416a8f79c349faa62bbaa1tom         VG_(addToXA)( parser->qparentE[parser->sp].Te.TyStOrUn.fieldRs,
341907de5ddba10bfebab8416a8f79c349faa62bbaa1tom                       &posn );
342007de5ddba10bfebab8416a8f79c349faa62bbaa1tom         /* And record the child itself */
342107de5ddba10bfebab8416a8f79c349faa62bbaa1tom         goto acquire_Field;
342207de5ddba10bfebab8416a8f79c349faa62bbaa1tom      } else {
342307de5ddba10bfebab8416a8f79c349faa62bbaa1tom         /* Member with no location - this can happen with static
342407de5ddba10bfebab8416a8f79c349faa62bbaa1tom            const members in C++ code which are compile time constants
342507de5ddba10bfebab8416a8f79c349faa62bbaa1tom            that do no exist in the class. They're not of any interest
342607de5ddba10bfebab8416a8f79c349faa62bbaa1tom            to us so we ignore them. */
3427d9df0ea979e3dd5b732b8cced076a105fa45f352philippe         ML_(TyEnt__make_EMPTY)(&fieldE);
3428b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3429b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3430b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3431b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_array_type) {
34329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
34339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = posn;
34349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyArray;
34359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyArray.typeR = D3_INVALID_CUOFF;
34369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyArray.boundRs
34379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ptD.array_type.1",
34389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                       ML_(dinfo_free),
34399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                       sizeof(UWord) );
3440746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
3441b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
3442746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
3443746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
3444746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
3445b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
34465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
34475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_type && cts.szB > 0) {
34485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyArray.typeR
34495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = cook_die_using_form( cc, (UWord)cts.u.val, form );
3450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3451b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
34529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (typeE.Te.TyArray.typeR == D3_INVALID_CUOFF)
34535c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
3454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* On't stack! */
34559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typestack_push( cc, parser, td3, &typeE, level );
3456b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      goto acquire_Type;
3457b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3458b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
34592acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   /* this is a subrange type defining the bounds of an array. */
34602acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   if (dtag == DW_TAG_subrange_type
34612acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj       && subrange_type_denotes_array_bounds(parser, dtag)) {
3462b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_lower = False;
3463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_upper = False;
3464b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool have_count = False;
3465b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Long lower = 0;
3466b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Long upper = 0;
3467b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3468b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      switch (parser->language) {
3469b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         case 'C': have_lower = True;  lower = 0; break;
3470b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         case 'F': have_lower = True;  lower = 1; break;
3471b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         case '?': have_lower = False; break;
34722acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj         case 'A': have_lower = False; break;
3473b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         default:  vg_assert(0); /* assured us by handling of
3474b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                    DW_TAG_compile_unit in this fn */
3475b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
34769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
34779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)( &boundE, 0, sizeof(boundE) );
34789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      boundE.cuOff = D3_INVALID_CUOFF;
34799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      boundE.tag   = Te_Bound;
3480746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
3481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
3482746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
3483746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
3484746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
3485b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
34865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
34875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_lower_bound && cts.szB > 0) {
34885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            lower      = (Long)cts.u.val;
3489b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_lower = True;
3490b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
34915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_upper_bound && cts.szB > 0) {
34925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            upper      = (Long)cts.u.val;
3493b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_upper = True;
3494b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
34955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_count && cts.szB > 0) {
34965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            /*count    = (Long)cts.u.val;*/
3497b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_count = True;
3498b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3499b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3500b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* FIXME: potentially skip the rest if no parent present, since
3501b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         it could be the case that this subrange type is free-standing
3502b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (not being used to describe the bounds of a containing array
3503b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         type) */
3504b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Do we have a plausible parent? */
35055c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe      if (typestack_is_empty(parser)) goto_bad_DIE;
35069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp]));
35079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(parser->qparentE[parser->sp].cuOff != D3_INVALID_CUOFF);
35085c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe      if (level != parser->qlevel[parser->sp]+1) goto_bad_DIE;
35095c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe      if (parser->qparentE[parser->sp].tag != Te_TyArray) goto_bad_DIE;
3510b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3511b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Figure out if we have a definite range or not */
3512b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (have_lower && have_upper && (!have_count)) {
35139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.knownL = True;
35149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.knownU = True;
35159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.boundL = lower;
35169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.boundU = upper;
351772259920f8cad01708271879caca023969463d16tom      }
3518b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      else if (have_lower && (!have_upper) && (!have_count)) {
35199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.knownL = True;
35209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.knownU = False;
35219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.boundL = lower;
35229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         boundE.Te.Bound.boundU = 0;
352372259920f8cad01708271879caca023969463d16tom      }
352472259920f8cad01708271879caca023969463d16tom      else if ((!have_lower) && have_upper && (!have_count)) {
352572259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.knownL = False;
352672259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.knownU = True;
352772259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.boundL = 0;
352872259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.boundU = upper;
352972259920f8cad01708271879caca023969463d16tom      }
353072259920f8cad01708271879caca023969463d16tom      else if ((!have_lower) && (!have_upper) && (!have_count)) {
353172259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.knownL = False;
353272259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.knownU = False;
353372259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.boundL = 0;
353472259920f8cad01708271879caca023969463d16tom         boundE.Te.Bound.boundU = 0;
3535b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      } else {
3536b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         /* FIXME: handle more cases */
35375c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
3538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3539b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3540b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Record this bound in the parent */
35419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      boundE.cuOff = posn;
35429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(parser->qparentE[parser->sp].Te.TyArray.boundRs);
35439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(addToXA)( parser->qparentE[parser->sp].Te.TyArray.boundRs,
3544471d6b3eba2d617279c3954a13e322174a0eec13sewardj                    &boundE.cuOff );
3545b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* And record the child itself */
35469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      goto acquire_Bound;
3547b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3548b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
35492acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   /* typedef or subrange_type other than array bounds. */
35502acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj   if (dtag == DW_TAG_typedef
35512acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj       || (dtag == DW_TAG_subrange_type
35522acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj           && !subrange_type_denotes_array_bounds(parser, dtag))) {
35532acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      /* subrange_type other than array bound is only for Ada. */
35542acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      vg_assert (dtag == DW_TAG_typedef || parser->language == 'A');
35552acc87cac77cedb3884e9e3a5188bac6edda5aeesewardj      /* We can pick up a new typedef/subrange_type any time. */
35569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
35579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = D3_INVALID_CUOFF;
35589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyTyDef;
35599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyTyDef.name = NULL;
35609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyTyDef.typeR = D3_INVALID_CUOFF;
3561746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
3562b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
3563746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
3564746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
3565746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
3566b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
35675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
35685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_name && cts.szB < 0) {
35699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            typeE.Te.TyTyDef.name
35705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = ML_(cur_read_strdup)( cts.u.cur,
35715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       "di.readdwarf3.ptD.typedef.1" );
3572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
35735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_type && cts.szB > 0) {
35745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyTyDef.typeR
35755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = cook_die_using_form( cc, (UWord)cts.u.val, form );
3576b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3577b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3578e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw      /* Do we have something that looks sane?
3579e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw         gcc gnat Ada generates minimal typedef
3580e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw         such as the below
3581e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw         <6><91cc>: DW_TAG_typedef
3582e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw            DW_AT_abstract_ori: <9066>
3583e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw         g++ for OMP can generate artificial functions that have
3584e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw         parameters that refer to pointers to unnamed typedefs.
3585e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw         See https://bugs.kde.org/show_bug.cgi?id=273475
3586e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw         So we cannot require a name for a DW_TAG_typedef.
3587e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw      */
3588e5cf4510a6c26279e0b7f625dc615f94b8fbdebfmjw      goto acquire_Type;
3589b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3590b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3591b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (dtag == DW_TAG_subroutine_type) {
3592b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* function type? just record that one fact and ask no
3593b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         further questions. */
35949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
35959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = D3_INVALID_CUOFF;
35969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyFn;
3597b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      goto acquire_Type;
3598b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3600c81436d329fa0be3dfb4c2bfd1b4783e0489884fmjw   if (dtag == DW_TAG_volatile_type || dtag == DW_TAG_const_type
3601c81436d329fa0be3dfb4c2bfd1b4783e0489884fmjw       || dtag == DW_TAG_restrict_type) {
3602b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Int have_ty = 0;
36039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(memset)(&typeE, 0, sizeof(typeE));
36049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.cuOff = D3_INVALID_CUOFF;
36059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.tag   = Te_TyQual;
36069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyQual.qual
3607c81436d329fa0be3dfb4c2bfd1b4783e0489884fmjw         = (dtag == DW_TAG_volatile_type ? 'V'
3608c81436d329fa0be3dfb4c2bfd1b4783e0489884fmjw            : (dtag == DW_TAG_const_type ? 'C' : 'R'));
3609b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* target type defaults to 'void' */
36109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      typeE.Te.TyQual.typeR = D3_FAKEVOID_CUOFF;
3611746e97e7098def65d59c79d5d661f9a757a837cdphilippe      nf_i = 0;
3612b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
3613746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_AT   attr = (DW_AT)  abbv->nf[nf_i].at_name;
3614746e97e7098def65d59c79d5d661f9a757a837cdphilippe         DW_FORM form = (DW_FORM)abbv->nf[nf_i].at_form;
3615746e97e7098def65d59c79d5d661f9a757a837cdphilippe         nf_i++;
3616b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (attr == 0 && form == 0) break;
36175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         get_Form_contents( &cts, cc, c_die, False/*td3*/, form );
36185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (attr == DW_AT_type && cts.szB > 0) {
36195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            typeE.Te.TyQual.typeR
36205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               = cook_die_using_form( cc, (UWord)cts.u.val, form );
3621b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            have_ty++;
3622b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
3623b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
3624b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* gcc sometimes generates DW_TAG_const/volatile_type without
3625b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         DW_AT_type and GDB appears to interpret the type as 'const
3626b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         void' (resp. 'volatile void').  So just allow it .. */
3627b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (have_ty == 1 || have_ty == 0)
3628b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         goto acquire_Type;
3629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      else
36305c5b8fc1da94607b804e408a38f073c4d6f3b76fphilippe         goto_bad_DIE;
3631b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3632b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3633e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart   /*
3634e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart    * Treat DW_TAG_unspecified_type as type void. An example of DW_TAG_unspecified_type:
3635e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart    *
3636e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart    * $ readelf --debug-dump /usr/lib/debug/usr/lib/libstdc++.so.6.0.16.debug
3637e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart    *  <1><10d4>: Abbrev Number: 53 (DW_TAG_unspecified_type)
3638e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart    *     <10d5>   DW_AT_name        : (indirect string, offset: 0xdb7): decltype(nullptr)
3639e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart    */
3640e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart   if (dtag == DW_TAG_unspecified_type) {
3641e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart      VG_(memset)(&typeE, 0, sizeof(typeE));
3642e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart      typeE.cuOff           = D3_INVALID_CUOFF;
3643e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart      typeE.tag             = Te_TyQual;
3644e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart      typeE.Te.TyQual.typeR = D3_FAKEVOID_CUOFF;
3645e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart      goto acquire_Type;
3646e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart   }
3647e64c5a9a6c0d9c87bc7a65629455d2ff7fb9bda4bart
3648b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* else ignore this DIE */
3649b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return;
3650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
3651b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3652b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  acquire_Type:
3653b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (0) VG_(printf)("YYYY Acquire Type\n");
36549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(ML_(TyEnt__is_type)( &typeE ));
36559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(typeE.cuOff == D3_INVALID_CUOFF || typeE.cuOff == posn);
36569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   typeE.cuOff = posn;
36579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(addToXA)( tyents, &typeE );
3658b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return;
3659b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
3660b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3661b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  acquire_Atom:
3662b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (0) VG_(printf)("YYYY Acquire Atom\n");
36639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(atomE.tag == Te_Atom);
36649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(atomE.cuOff == D3_INVALID_CUOFF || atomE.cuOff == posn);
36659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   atomE.cuOff = posn;
36669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(addToXA)( tyents, &atomE );
3667b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return;
3668b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
3669b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
36709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj  acquire_Field:
3671b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* For union members, Expr should be absent */
36729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (0) VG_(printf)("YYYY Acquire Field\n");
36739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(fieldE.tag == Te_Field);
36743c9cf3442185b5891e15450d6e3058aeff6796fetom   vg_assert(fieldE.Te.Field.nLoc <= 0 || fieldE.Te.Field.pos.loc != NULL);
36753c9cf3442185b5891e15450d6e3058aeff6796fetom   vg_assert(fieldE.Te.Field.nLoc != 0 || fieldE.Te.Field.pos.loc == NULL);
36769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (fieldE.Te.Field.isStruct) {
36773c9cf3442185b5891e15450d6e3058aeff6796fetom      vg_assert(fieldE.Te.Field.nLoc != 0);
36789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   } else {
36799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(fieldE.Te.Field.nLoc == 0);
36809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
36819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(fieldE.cuOff == D3_INVALID_CUOFF || fieldE.cuOff == posn);
36829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   fieldE.cuOff = posn;
36839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(addToXA)( tyents, &fieldE );
3684b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return;
3685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
3686b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
36879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj  acquire_Bound:
36889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (0) VG_(printf)("YYYY Acquire Bound\n");
36899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(boundE.tag == Te_Bound);
36909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(boundE.cuOff == D3_INVALID_CUOFF || boundE.cuOff == posn);
36919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   boundE.cuOff = posn;
36929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(addToXA)( tyents, &boundE );
3693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return;
3694b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
3695b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3696b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj  bad_DIE:
3697896a3bfd1b98aa3358a2e77be3bb728cb3d2926fphilippe   dump_bad_die_and_barf("parse_type_DIE", dtag, posn, level,
3698a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                         c_die, saved_die_c_offset,
3699a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                         abbv,
3700a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                         cc);
3701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
3702b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3703b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3704b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3705b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
3706b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
37079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/*--- Compression of type DIE information                  ---*/
3708b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
3709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
3710b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
37119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic UWord chase_cuOff ( Bool* changed,
37129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                           XArray* /* of TyEnt */ ents,
37139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                           TyEntIndexCache* ents_cache,
37149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                           UWord cuOff )
37159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
37169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEnt* ent;
37179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache, cuOff );
3718b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
37199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (!ent) {
37209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(printf)("chase_cuOff: no entry for 0x%05lx\n", cuOff);
37219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      *changed = False;
37229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      return cuOff;
37239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
372459a2d18d0ddfa241850017252b0804d469187d79sewardj
37259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   vg_assert(ent->tag != Te_EMPTY);
37269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (ent->tag != Te_INDIR) {
37279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      *changed = False;
37289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      return cuOff;
37299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   } else {
37309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ent->Te.INDIR.indR < cuOff);
37319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      *changed = True;
37329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      return ent->Te.INDIR.indR;
3733b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
37349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj}
3735b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
37369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic
37379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid chase_cuOffs_in_XArray ( Bool* changed,
37389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                              XArray* /* of TyEnt */ ents,
37399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                              TyEntIndexCache* ents_cache,
37409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                              /*MOD*/XArray* /* of UWord */ cuOffs )
37419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
37429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Bool b2 = False;
37439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Word i, n = VG_(sizeXA)( cuOffs );
37449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   for (i = 0; i < n; i++) {
37459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      Bool   b = False;
37469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      UWord* p = VG_(indexXA)( cuOffs, i );
37479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      *p = chase_cuOff( &b, ents, ents_cache, *p );
37489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (b)
37499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         b2 = True;
37509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
37519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   *changed = b2;
3752b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
3753b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
37549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic Bool TyEnt__subst_R_fields ( XArray* /* of TyEnt */ ents,
37559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                    TyEntIndexCache* ents_cache,
37569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                    /*MOD*/TyEnt* te )
37579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
37589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Bool b, changed = False;
37599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   switch (te->tag) {
37609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_EMPTY:
37619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
37629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_INDIR:
37639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         te->Te.INDIR.indR
37649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = chase_cuOff( &b, ents, ents_cache, te->Te.INDIR.indR );
37659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
37669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
37679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_UNKNOWN:
37689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
37699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_Atom:
37709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
37719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_Field:
37729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         te->Te.Field.typeR
37739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = chase_cuOff( &b, ents, ents_cache, te->Te.Field.typeR );
37749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
37759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
37769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_Bound:
37779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
37789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyBase:
37799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
37800e947cfedebda6da2e84fb61af431db5cf1275fcbart      case Te_TyPtr:
37810e947cfedebda6da2e84fb61af431db5cf1275fcbart      case Te_TyRef:
37820e947cfedebda6da2e84fb61af431db5cf1275fcbart      case Te_TyPtrMbr:
37830e947cfedebda6da2e84fb61af431db5cf1275fcbart      case Te_TyRvalRef:
37849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         te->Te.TyPorR.typeR
37859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = chase_cuOff( &b, ents, ents_cache, te->Te.TyPorR.typeR );
37869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
37879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
37889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyTyDef:
37899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         te->Te.TyTyDef.typeR
37909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = chase_cuOff( &b, ents, ents_cache, te->Te.TyTyDef.typeR );
37919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
37929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
37939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyStOrUn:
37949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyStOrUn.fieldRs );
37959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
37969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
37979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyEnum:
37989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyEnum.atomRs );
37999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
38009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
38019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyArray:
38029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         te->Te.TyArray.typeR
38039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = chase_cuOff( &b, ents, ents_cache, te->Te.TyArray.typeR );
38049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
38059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyArray.boundRs );
38069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
38079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
38089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyFn:
38099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
38109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyQual:
38119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         te->Te.TyQual.typeR
38129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            = chase_cuOff( &b, ents, ents_cache, te->Te.TyQual.typeR );
38139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         if (b) changed = True;
38149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
38159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      case Te_TyVoid:
38169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         break;
38179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      default:
38189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ML_(pp_TyEnt)(te);
38199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(0);
38209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
38219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   return changed;
38229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj}
382359a2d18d0ddfa241850017252b0804d469187d79sewardj
38249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Make a pass over 'ents'.  For each tyent, inspect the target of any
38259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   'R' or 'Rs' fields (those which refer to other tyents), and replace
38269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   any which point to INDIR nodes with the target of the indirection
38279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   (which should not itself be an indirection).  In summary, this
38289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   routine shorts out all references to indirection nodes. */
38299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic
38309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjWord dedup_types_substitution_pass ( /*MOD*/XArray* /* of TyEnt */ ents,
38319c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                     TyEntIndexCache* ents_cache )
38329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
38339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Word i, n, nChanged = 0;
38349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Bool b;
38359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   n = VG_(sizeXA)( ents );
38369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   for (i = 0; i < n; i++) {
38379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TyEnt* ent = VG_(indexXA)( ents, i );
38389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ent->tag != Te_EMPTY);
38399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* We have to substitute everything, even indirections, so as to
38409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ensure that chains of indirections don't build up. */
38419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      b = TyEnt__subst_R_fields( ents, ents_cache, ent );
38429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (b)
38439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         nChanged++;
38449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
384559a2d18d0ddfa241850017252b0804d469187d79sewardj
38469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   return nChanged;
38479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj}
384859a2d18d0ddfa241850017252b0804d469187d79sewardj
384959a2d18d0ddfa241850017252b0804d469187d79sewardj
38509c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Make a pass over 'ents', building a dictionary of TyEnts as we go.
38519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Look up each new tyent in the dictionary in turn.  If it is already
38529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   in the dictionary, replace this tyent with an indirection to the
38539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   existing one, and delete any malloc'd stuff hanging off this one.
38549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   In summary, this routine commons up all tyents that are identical
38559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   as defined by TyEnt__cmp_by_all_except_cuOff. */
38569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic
38579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjWord dedup_types_commoning_pass ( /*MOD*/XArray* /* of TyEnt */ ents )
3858b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
38599c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Word    n, i, nDeleted;
38609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   WordFM* dict; /* TyEnt* -> void */
38619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TyEnt*  ent;
38629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   UWord   keyW, valW;
38639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
38649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   dict = VG_(newFM)(
38659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj             ML_(dinfo_zalloc), "di.readdwarf3.dtcp.1",
38669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj             ML_(dinfo_free),
38679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj             (Word(*)(UWord,UWord)) ML_(TyEnt__cmp_by_all_except_cuOff)
38689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj          );
38699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
38709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   nDeleted = 0;
38719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   n = VG_(sizeXA)( ents );
38729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   for (i = 0; i < n; i++) {
38739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      ent = VG_(indexXA)( ents, i );
38749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ent->tag != Te_EMPTY);
38759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
38769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* Ignore indirections, although check that they are
38779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         not forming a cycle. */
38789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (ent->tag == Te_INDIR) {
38799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(ent->Te.INDIR.indR < ent->cuOff);
38809c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         continue;
38819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      }
3882b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
38839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      keyW = valW = 0;
38849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (VG_(lookupFM)( dict, &keyW, &valW, (UWord)ent )) {
38859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         /* it's already in the dictionary. */
38869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         TyEnt* old = (TyEnt*)keyW;
38879c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(valW == 0);
38889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(old != ent);
38899c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(old->tag != Te_INDIR);
38909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         /* since we are traversing the array in increasing order of
38919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            cuOff: */
38929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(old->cuOff < ent->cuOff);
38939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         /* So anyway, dump this entry and replace it with an
38949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            indirection to the one in the dictionary.  Note that the
38959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            assertion above guarantees that we cannot create cycles of
38969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            indirections, since we are always creating an indirection
38979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            to a tyent with a cuOff lower than this one. */
38989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ML_(TyEnt__make_EMPTY)( ent );
38999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ent->tag = Te_INDIR;
39009c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ent->Te.INDIR.indR = old->cuOff;
39019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         nDeleted++;
39029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      } else {
39039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         /* not in dictionary; add it and keep going. */
39049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         VG_(addToFM)( dict, (UWord)ent, 0 );
39059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      }
39069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
39079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
39089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(deleteFM)( dict, NULL, NULL );
390959a2d18d0ddfa241850017252b0804d469187d79sewardj
39109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   return nDeleted;
39119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj}
3912b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
3913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
39149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic
39159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjvoid dedup_types ( Bool td3,
39169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                   /*MOD*/XArray* /* of TyEnt */ ents,
39179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                   TyEntIndexCache* ents_cache )
39189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
39199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Word m, n, i, nDel, nSubst, nThresh;
39209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   if (0) td3 = True;
39219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
39229c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   n = VG_(sizeXA)( ents );
39239c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
39249c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* If a commoning pass and a substitution pass both make fewer than
39259c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      this many changes, just stop.  It's pointless to burn up CPU
39269c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      time trying to compress the last 1% or so out of the array. */
39279c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   nThresh = n / 200;
39289c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
39299c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* First we must sort .ents by its .cuOff fields, so we
39309c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      can index into it. */
39316bd9dc18c043927c1196caba20a327238a179c42florian   VG_(setCmpFnXA)( ents, (XACmpFn_t) ML_(TyEnt__cmp_by_cuOff_only) );
39329c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   VG_(sortXA)( ents );
39339c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
39349c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* Now repeatedly do commoning and substitution passes over
39359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      the array, until there are no more changes. */
39369c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   do {
39379c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      nDel   = dedup_types_commoning_pass ( ents );
39389c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      nSubst = dedup_types_substitution_pass ( ents, ents_cache );
39399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(nDel >= 0 && nSubst >= 0);
39409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TRACE_D3("   %ld deletions, %ld substitutions\n", nDel, nSubst);
39419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   } while (nDel > nThresh || nSubst > nThresh);
39429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
39439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /* Sanity check: all INDIR nodes should point at a non-INDIR thing.
39449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      In fact this should be true at the end of every loop iteration
39459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      above (a commoning pass followed by a substitution pass), but
39469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      checking it on every iteration is excessively expensive.  Note,
39479c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      this loop also computes 'm' for the stats printing below it. */
39489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   m = 0;
39499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   n = VG_(sizeXA)( ents );
395059a2d18d0ddfa241850017252b0804d469187d79sewardj   for (i = 0; i < n; i++) {
39519c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TyEnt *ent, *ind;
39529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      ent = VG_(indexXA)( ents, i );
39539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (ent->tag != Te_INDIR) continue;
39549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      m++;
39559c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      ind = ML_(TyEnts__index_by_cuOff)( ents, ents_cache,
39569c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                         ent->Te.INDIR.indR );
39579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ind);
39589c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ind->tag != Te_INDIR);
3959b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
3960b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
39619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   TRACE_D3("Overall: %ld before, %ld after\n", n, n-m);
39629c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj}
39639c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
39649c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
39659c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/*------------------------------------------------------------*/
39669c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/*---                                                      ---*/
39679c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/*--- Resolution of references to type DIEs                ---*/
39689c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/*---                                                      ---*/
39699c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/*------------------------------------------------------------*/
39709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
39719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj/* Make a pass through the (temporary) variables array.  Examine the
39729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   type of each variable, check is it found, and chase any Te_INDIRs.
39739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Postcondition is: each variable has a typeR field that refers to a
39749c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   valid type in tyents, or a Te_UNKNOWN, and is certainly guaranteed
39759c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   not to refer to a Te_INDIR.  (This is so that we can throw all the
39769c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Te_INDIRs away later). */
39779c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
39789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj__attribute__((noinline))
39799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic void resolve_variable_types (
39806bd9dc18c043927c1196caba20a327238a179c42florian               void (*barf)( const HChar* ) __attribute__((noreturn)),
39819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               /*R-O*/XArray* /* of TyEnt */ ents,
39829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               /*MOD*/TyEntIndexCache* ents_cache,
39839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj               /*MOD*/XArray* /* of TempVar* */ vars
39849c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj            )
39859c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj{
39869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Word i, n;
398759a2d18d0ddfa241850017252b0804d469187d79sewardj   n = VG_(sizeXA)( vars );
398859a2d18d0ddfa241850017252b0804d469187d79sewardj   for (i = 0; i < n; i++) {
398959a2d18d0ddfa241850017252b0804d469187d79sewardj      TempVar* var = *(TempVar**)VG_(indexXA)( vars, i );
39909c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* This is the stated type of the variable.  But it might be
39919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         an indirection, so be careful. */
39929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TyEnt* ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache,
39939c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                                var->typeR );
39949c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (ent && ent->tag == Te_INDIR) {
39959c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache,
39969c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                            ent->Te.INDIR.indR );
39979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(ent);
39989c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         vg_assert(ent->tag != Te_INDIR);
39999c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      }
4000b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
40019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* Deal first with "normal" cases */
40029c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (ent && ML_(TyEnt__is_type)(ent)) {
40039c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         var->typeR = ent->cuOff;
40049c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         continue;
40059c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      }
40069c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
40079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* If there's no ent, it probably we did not manage to read a
40089c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         type at the cuOffset which is stated as being this variable's
40099c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         type.  Maybe a deficiency in parse_type_DIE.  Complain. */
40109c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      if (ent == NULL) {
40119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         VG_(printf)("\n: Invalid cuOff = 0x%05lx\n", var->typeR );
40129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         barf("resolve_variable_types: "
40139c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj              "cuOff does not refer to a known type");
40149c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      }
40159c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ent);
40169c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* If ent has any other tag, something bad happened, along the
40179c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         lines of var->typeR not referring to a type at all. */
40189c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      vg_assert(ent->tag == Te_UNKNOWN);
40199c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      /* Just accept it; the type will be useless, but at least keep
40209c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         going. */
40219c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      var->typeR = ent->cuOff;
4022b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4023b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4024b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4025b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4026b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
4027b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
4028b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- Parsing of Compilation Units                         ---*/
4029b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
4030b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
4031b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
40326bd9dc18c043927c1196caba20a327238a179c42florianstatic Int cmp_TempVar_by_dioff ( const void* v1, const void* v2 ) {
40333e7986312a0ffc7646b0552d4c4ea3744a870e73florian   const TempVar* t1 = *(const TempVar *const *)v1;
40343e7986312a0ffc7646b0552d4c4ea3744a870e73florian   const TempVar* t2 = *(const TempVar *const *)v2;
4035b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (t1->dioff < t2->dioff) return -1;
4036b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (t1->dioff > t2->dioff) return 1;
4037b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   return 0;
4038b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4039b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
40409c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjstatic void read_DIE (
40419c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/WordFM* /* of (XArray* of AddrRange, void) */ rangestree,
40429c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/XArray* /* of TyEnt */ tyents,
40439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/XArray* /* of TempVar* */ tempvars,
40449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/XArray* /* of GExpr* */ gexprs,
40459c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/D3TypeParser* typarser,
40469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   /*MOD*/D3VarParser* varparser,
4047a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   /*MOD*/D3InlParser* inlparser,
40489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   Cursor* c, Bool td3, CUConst* cc, Int level
40499c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj)
4050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4051746e97e7098def65d59c79d5d661f9a757a837cdphilippe   g_abbv *abbv;
4052b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   ULong  atag, abbv_code;
4053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UWord  posn;
4054b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UInt   has_children;
4055746e97e7098def65d59c79d5d661f9a757a837cdphilippe   UWord  start_die_c_offset;
4056746e97e7098def65d59c79d5d661f9a757a837cdphilippe   UWord  after_die_c_offset;
4057a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   // If the DIE we will parse has a sibling and the parser(s) are
4058a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   // all indicating that parse_children is not necessary, then
4059a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   // we will skip the children by jumping to the sibling of this DIE
4060a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   // (if it has a sibling).
4061a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   UWord  sibling = 0;
4062a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   Bool   parse_children = False;
4063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* --- Deal with this DIE --- */
4065d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   posn      = cook_die( cc, get_position_of_Cursor( c ) );
4066b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   abbv_code = get_ULEB128( c );
4067746e97e7098def65d59c79d5d661f9a757a837cdphilippe   abbv = get_abbv(cc, abbv_code);
4068746e97e7098def65d59c79d5d661f9a757a837cdphilippe   atag      = abbv->atag;
406986be6ed340d2373ffded269f57aa87765430ddccphilippe
4070e0bd5910153720d5d15697db8063d0d4caa59d8fphilippe   if (TD3) {
407186be6ed340d2373ffded269f57aa87765430ddccphilippe      TRACE_D3("\n");
407286be6ed340d2373ffded269f57aa87765430ddccphilippe      trace_DIE ((DW_TAG)atag, posn, level,
407386be6ed340d2373ffded269f57aa87765430ddccphilippe                 get_position_of_Cursor( c ), abbv, cc);
407486be6ed340d2373ffded269f57aa87765430ddccphilippe   }
4075b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (atag == 0)
4077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("read_DIE: invalid zero tag on DIE");
4078b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4079746e97e7098def65d59c79d5d661f9a757a837cdphilippe   has_children = abbv->has_children;
4080b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (has_children != DW_children_no && has_children != DW_children_yes)
4081b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      cc->barf("read_DIE: invalid has_children value");
4082b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4083b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* We're set up to look at the fields of this DIE.  Hand it off to
4084b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      any parser(s) that want to see it.  Since they will in general
40850d2ea9d1cfd6f1fff0992096c2d15881becfe2e1philippe      advance the DIE cursor, remember the current settings so that we
4086d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe      can then back up. . */
4087b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   start_die_c_offset  = get_position_of_Cursor( c );
4088d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe   after_die_c_offset  = 0; // set to c position if a parser has read the DIE.
4089b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4090a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (VG_(clo_read_var_info)) {
4091a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      parse_type_DIE( tyents,
4092a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      typarser,
4093a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      (DW_TAG)atag,
4094a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      posn,
4095a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      level,
4096a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      c,     /* DIE cursor */
4097a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      abbv,  /* abbrev */
4098a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      cc,
4099a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      td3 );
4100d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe      if (get_position_of_Cursor( c ) != start_die_c_offset) {
4101d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe         after_die_c_offset = get_position_of_Cursor( c );
4102d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe         set_position_of_Cursor( c, start_die_c_offset );
4103d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe      }
4104a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4105a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      parse_var_DIE( rangestree,
4106a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     tempvars,
4107a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     gexprs,
4108a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     varparser,
4109a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     (DW_TAG)atag,
4110a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     posn,
4111a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     level,
4112a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     c,     /* DIE cursor */
4113a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     abbv,  /* abbrev */
4114a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     cc,
4115a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     td3 );
4116d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe      if (get_position_of_Cursor( c ) != start_die_c_offset) {
4117d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe         after_die_c_offset = get_position_of_Cursor( c );
4118d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe         set_position_of_Cursor( c, start_die_c_offset );
4119d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe      }
4120a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4121a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      parse_children = True;
4122d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe      // type and var parsers do not have logic to skip childrens and establish
4123d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe      // the value of sibling.
4124a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
4125a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4126a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (VG_(clo_read_inline_info)) {
4127d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe      inlparser->sibling = 0;
4128a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      parse_children =
4129a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         parse_inl_DIE( inlparser,
4130a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        (DW_TAG)atag,
4131a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        posn,
4132a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        level,
4133a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        c,     /* DIE cursor */
4134a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        abbv, /* abbrev */
4135a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        cc,
4136a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        td3 )
4137a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         || parse_children;
4138d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe      if (get_position_of_Cursor( c ) != start_die_c_offset) {
4139d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe         after_die_c_offset = get_position_of_Cursor( c );
4140d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe         // Last parser, no need to reset the cursor to start_die_c_offset.
4141d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe      }
4142d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe      if (sibling == 0)
4143d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe         sibling = inlparser->sibling;
4144d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe      vg_assert (inlparser->sibling == 0 || inlparser->sibling == sibling);
4145a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
4146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4147d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe   if (after_die_c_offset > 0) {
4148d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe      // DIE was read by a parser above, so we know where the DIE ends.
4149d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe      set_position_of_Cursor( c, after_die_c_offset );
4150d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe   } else {
4151e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      /* No parser has parsed this DIE. So, we need to skip the DIE,
4152e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe         in order to read the next DIE.
4153d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe         At the same time, establish sibling value if the DIE has one. */
4154e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      TRACE_D3("    uninteresting DIE -> skipping ...\n");
4155e1f94b89c69cb3a71dce6800f6dbf8d045d935f6philippe      skip_DIE (&sibling, c, abbv, cc);
4156d16fb63bfee12beb45f85695b4aed7a18bde56e1philippe   }
4157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4158a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   /* --- Now recurse into its children, if any
4159a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      and the parsing of the children is requested by a parser --- */
4160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (has_children == DW_children_yes) {
4161a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      if (parse_children || sibling == 0) {
4162a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (0) TRACE_D3("BEGIN children of level %d\n", level);
4163a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         while (True) {
4164a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            atag = peek_ULEB128( c );
4165a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (atag == 0) break;
4166a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            read_DIE( rangestree, tyents, tempvars, gexprs,
4167a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      typarser, varparser, inlparser,
4168a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                      c, td3, cc, level+1 );
4169a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
4170a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* Now we need to eat the terminating zero */
4171a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         atag = get_ULEB128( c );
4172a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         vg_assert(atag == 0);
4173a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (0) TRACE_D3("END children of level %d\n", level);
4174a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      } else {
4175a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         // We can skip the childrens, by jumping to the sibling
417686be6ed340d2373ffded269f57aa87765430ddccphilippe         TRACE_D3("    SKIPPING DIE's children,"
4177a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                  "jumping to sibling <%d><%lx>\n",
4178a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                  level, sibling);
4179a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         set_position_of_Cursor( c, sibling );
4180b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
4184b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4185c9831572483ed485438553d4c39686605d2625d6philippestatic void trace_debug_loc (struct _DebugInfo* di,
4186c9831572483ed485438553d4c39686605d2625d6philippe                             __attribute__((noreturn)) void (*barf)( const HChar* ),
4187c9831572483ed485438553d4c39686605d2625d6philippe                             DiSlice escn_debug_loc)
4188b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
4189b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#if 0
4190b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* This doesn't work properly because it assumes all entries are
4191b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      packed end to end, with no holes.  But that doesn't always
4192b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      appear to be the case, so it loses sync.  And the D3 spec
4193b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      doesn't appear to require a no-hole situation either. */
4194b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Display .debug_loc */
4195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Addr  dl_base;
4196b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   UWord dl_offset;
4197b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   Cursor loc; /* for showing .debug_loc */
4198c9831572483ed485438553d4c39686605d2625d6philippe   Bool td3 = di->trace_symtab;
4199c9831572483ed485438553d4c39686605d2625d6philippe
4200b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n");
4201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n------ The contents of .debug_loc ------\n");
4202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("    Offset   Begin    End      Expression\n");
4203c9831572483ed485438553d4c39686605d2625d6philippe   if (ML_(sli_is_valid)(escn_debug_loc)) {
4204c9831572483ed485438553d4c39686605d2625d6philippe      init_Cursor( &loc, escn_debug_loc, 0, barf,
4205c9831572483ed485438553d4c39686605d2625d6philippe                   "Overrun whilst reading .debug_loc section(1)" );
4206c9831572483ed485438553d4c39686605d2625d6philippe      dl_base = 0;
4207c9831572483ed485438553d4c39686605d2625d6philippe      dl_offset = 0;
4208c9831572483ed485438553d4c39686605d2625d6philippe      while (True) {
4209c9831572483ed485438553d4c39686605d2625d6philippe         UWord  w1, w2;
4210c9831572483ed485438553d4c39686605d2625d6philippe         UWord  len;
4211c9831572483ed485438553d4c39686605d2625d6philippe         if (is_at_end_Cursor( &loc ))
4212c9831572483ed485438553d4c39686605d2625d6philippe            break;
4213b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4214c9831572483ed485438553d4c39686605d2625d6philippe         /* Read a (host-)word pair.  This is something of a hack since
4215c9831572483ed485438553d4c39686605d2625d6philippe            the word size to read is really dictated by the ELF file;
4216c9831572483ed485438553d4c39686605d2625d6philippe            however, we assume we're reading a file with the same
4217c9831572483ed485438553d4c39686605d2625d6philippe            word-sizeness as the host.  Reasonably enough. */
4218c9831572483ed485438553d4c39686605d2625d6philippe         w1 = get_UWord( &loc );
4219c9831572483ed485438553d4c39686605d2625d6philippe         w2 = get_UWord( &loc );
4220b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4221c9831572483ed485438553d4c39686605d2625d6philippe         if (w1 == 0 && w2 == 0) {
4222c9831572483ed485438553d4c39686605d2625d6philippe            /* end of list.  reset 'base' */
4223c9831572483ed485438553d4c39686605d2625d6philippe            TRACE_D3("    %08lx <End of list>\n", dl_offset);
4224c9831572483ed485438553d4c39686605d2625d6philippe            dl_base = 0;
4225c9831572483ed485438553d4c39686605d2625d6philippe            dl_offset = get_position_of_Cursor( &loc );
4226c9831572483ed485438553d4c39686605d2625d6philippe            continue;
4227c9831572483ed485438553d4c39686605d2625d6philippe         }
4228b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4229c9831572483ed485438553d4c39686605d2625d6philippe         if (w1 == -1UL) {
4230c9831572483ed485438553d4c39686605d2625d6philippe            /* new value for 'base' */
4231c9831572483ed485438553d4c39686605d2625d6philippe            TRACE_D3("    %08lx %16lx %08lx (base address)\n",
4232c9831572483ed485438553d4c39686605d2625d6philippe                     dl_offset, w1, w2);
4233c9831572483ed485438553d4c39686605d2625d6philippe            dl_base = w2;
4234c9831572483ed485438553d4c39686605d2625d6philippe            continue;
4235c9831572483ed485438553d4c39686605d2625d6philippe         }
4236c9831572483ed485438553d4c39686605d2625d6philippe
4237c9831572483ed485438553d4c39686605d2625d6philippe         /* else a location expression follows */
4238c9831572483ed485438553d4c39686605d2625d6philippe         TRACE_D3("    %08lx %08lx %08lx ",
4239c9831572483ed485438553d4c39686605d2625d6philippe                  dl_offset, w1 + dl_base, w2 + dl_base);
4240c9831572483ed485438553d4c39686605d2625d6philippe         len = (UWord)get_UShort( &loc );
4241c9831572483ed485438553d4c39686605d2625d6philippe         while (len > 0) {
4242c9831572483ed485438553d4c39686605d2625d6philippe            UChar byte = get_UChar( &loc );
4243c9831572483ed485438553d4c39686605d2625d6philippe            TRACE_D3("%02x", (UInt)byte);
4244c9831572483ed485438553d4c39686605d2625d6philippe            len--;
4245c9831572483ed485438553d4c39686605d2625d6philippe         }
4246c9831572483ed485438553d4c39686605d2625d6philippe         TRACE_SYMTAB("\n");
4247b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4248b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4249b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
4250c9831572483ed485438553d4c39686605d2625d6philippe}
4251c9831572483ed485438553d4c39686605d2625d6philippe
4252c9831572483ed485438553d4c39686605d2625d6philippestatic void trace_debug_ranges (struct _DebugInfo* di,
4253c9831572483ed485438553d4c39686605d2625d6philippe                                __attribute__((noreturn)) void (*barf)( const HChar* ),
4254c9831572483ed485438553d4c39686605d2625d6philippe                                DiSlice escn_debug_ranges)
4255c9831572483ed485438553d4c39686605d2625d6philippe{
4256c9831572483ed485438553d4c39686605d2625d6philippe   Cursor ranges; /* for showing .debug_ranges */
4257c9831572483ed485438553d4c39686605d2625d6philippe   Addr  dr_base;
4258c9831572483ed485438553d4c39686605d2625d6philippe   UWord dr_offset;
4259c9831572483ed485438553d4c39686605d2625d6philippe   Bool td3 = di->trace_symtab;
4260b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4261b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Display .debug_ranges */
4262b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n");
4263b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n------ The contents of .debug_ranges ------\n");
4264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("    Offset   Begin    End\n");
42655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (ML_(sli_is_valid)(escn_debug_ranges)) {
42665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      init_Cursor( &ranges, escn_debug_ranges, 0, barf,
42675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                   "Overrun whilst reading .debug_ranges section(1)" );
42685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      dr_base = 0;
42695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      dr_offset = 0;
42705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      while (True) {
42715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UWord  w1, w2;
4272b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
42735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (is_at_end_Cursor( &ranges ))
42745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            break;
4275b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
42765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         /* Read a (host-)word pair.  This is something of a hack since
42775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            the word size to read is really dictated by the ELF file;
42785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            however, we assume we're reading a file with the same
42795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            word-sizeness as the host.  Reasonably enough. */
42805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         w1 = get_UWord( &ranges );
42815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         w2 = get_UWord( &ranges );
42825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
42835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (w1 == 0 && w2 == 0) {
42845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            /* end of list.  reset 'base' */
42855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            TRACE_D3("    %08lx <End of list>\n", dr_offset);
42865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            dr_base = 0;
42875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            dr_offset = get_position_of_Cursor( &ranges );
42885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            continue;
42895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
4290b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
42915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (w1 == -1UL) {
42925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            /* new value for 'base' */
42935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            TRACE_D3("    %08lx %16lx %08lx (base address)\n",
42945d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                     dr_offset, w1, w2);
42955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            dr_base = w2;
42965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            continue;
42975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
4298b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
42995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         /* else a range [w1+base, w2+base) is denoted */
43005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("    %08lx %08lx %08lx\n",
43015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  dr_offset, w1 + dr_base, w2 + dr_base);
4302b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4303b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4304c9831572483ed485438553d4c39686605d2625d6philippe}
4305c9831572483ed485438553d4c39686605d2625d6philippe
4306c9831572483ed485438553d4c39686605d2625d6philippestatic void trace_debug_abbrev (struct _DebugInfo* di,
4307c9831572483ed485438553d4c39686605d2625d6philippe                                __attribute__((noreturn)) void (*barf)( const HChar* ),
4308c9831572483ed485438553d4c39686605d2625d6philippe                                DiSlice escn_debug_abbv)
4309c9831572483ed485438553d4c39686605d2625d6philippe{
4310c9831572483ed485438553d4c39686605d2625d6philippe   Cursor abbv; /* for showing .debug_abbrev */
4311c9831572483ed485438553d4c39686605d2625d6philippe   Bool td3 = di->trace_symtab;
4312b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Display .debug_abbrev */
4314b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n");
4315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n------ The contents of .debug_abbrev ------\n");
43165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (ML_(sli_is_valid)(escn_debug_abbv)) {
43175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      init_Cursor( &abbv, escn_debug_abbv, 0, barf,
43185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                   "Overrun whilst reading .debug_abbrev section" );
4319b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
43205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (is_at_end_Cursor( &abbv ))
43215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            break;
43225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         /* Read one abbreviation table */
43235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("  Number TAG\n");
4324b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         while (True) {
43255d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ULong atag;
43265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            UInt  has_children;
43275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ULong acode = get_ULEB128( &abbv );
43285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            if (acode == 0) break; /* end of the table */
43295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            atag = get_ULEB128( &abbv );
43305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            has_children = get_UChar( &abbv );
43315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            TRACE_D3("   %llu      %s    [%s]\n",
43325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                     acode, ML_(pp_DW_TAG)(atag),
43335d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                            ML_(pp_DW_children)(has_children));
43345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            while (True) {
43355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               ULong at_name = get_ULEB128( &abbv );
43365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               ULong at_form = get_ULEB128( &abbv );
43375d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               if (at_name == 0 && at_form == 0) break;
43385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               TRACE_D3("    %18s %s\n",
43395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                        ML_(pp_DW_AT)(at_name), ML_(pp_DW_FORM)(at_form));
43405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            }
4341b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
4342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4343b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4344c9831572483ed485438553d4c39686605d2625d6philippe}
4345c9831572483ed485438553d4c39686605d2625d6philippe
4346c9831572483ed485438553d4c39686605d2625d6philippestatic
4347c9831572483ed485438553d4c39686605d2625d6philippevoid new_dwarf3_reader_wrk (
4348c9831572483ed485438553d4c39686605d2625d6philippe   struct _DebugInfo* di,
4349c9831572483ed485438553d4c39686605d2625d6philippe   __attribute__((noreturn)) void (*barf)( const HChar* ),
4350c9831572483ed485438553d4c39686605d2625d6philippe   DiSlice escn_debug_info,      DiSlice escn_debug_types,
4351c9831572483ed485438553d4c39686605d2625d6philippe   DiSlice escn_debug_abbv,      DiSlice escn_debug_line,
4352c9831572483ed485438553d4c39686605d2625d6philippe   DiSlice escn_debug_str,       DiSlice escn_debug_ranges,
4353c9831572483ed485438553d4c39686605d2625d6philippe   DiSlice escn_debug_loc,       DiSlice escn_debug_info_alt,
4354c9831572483ed485438553d4c39686605d2625d6philippe   DiSlice escn_debug_abbv_alt,  DiSlice escn_debug_line_alt,
4355c9831572483ed485438553d4c39686605d2625d6philippe   DiSlice escn_debug_str_alt
4356c9831572483ed485438553d4c39686605d2625d6philippe)
4357c9831572483ed485438553d4c39686605d2625d6philippe{
4358c9831572483ed485438553d4c39686605d2625d6philippe   XArray* /* of TyEnt */     tyents = NULL;
4359c9831572483ed485438553d4c39686605d2625d6philippe   XArray* /* of TyEnt */     tyents_to_keep = NULL;
4360c9831572483ed485438553d4c39686605d2625d6philippe   XArray* /* of GExpr* */    gexprs = NULL;
4361c9831572483ed485438553d4c39686605d2625d6philippe   XArray* /* of TempVar* */  tempvars = NULL;
4362c9831572483ed485438553d4c39686605d2625d6philippe   WordFM* /* of (XArray* of AddrRange, void) */ rangestree = NULL;
4363c9831572483ed485438553d4c39686605d2625d6philippe   TyEntIndexCache* tyents_cache = NULL;
4364c9831572483ed485438553d4c39686605d2625d6philippe   TyEntIndexCache* tyents_to_keep_cache = NULL;
4365c9831572483ed485438553d4c39686605d2625d6philippe   TempVar *varp, *varp2;
4366c9831572483ed485438553d4c39686605d2625d6philippe   GExpr* gexpr;
4367c9831572483ed485438553d4c39686605d2625d6philippe   Cursor info; /* primary cursor for parsing .debug_info */
4368c9831572483ed485438553d4c39686605d2625d6philippe   D3TypeParser typarser;
4369c9831572483ed485438553d4c39686605d2625d6philippe   D3VarParser varparser;
4370c9831572483ed485438553d4c39686605d2625d6philippe   D3InlParser inlparser;
4371c9831572483ed485438553d4c39686605d2625d6philippe   Word  i, j, n;
4372c9831572483ed485438553d4c39686605d2625d6philippe   Bool td3 = di->trace_symtab;
4373c9831572483ed485438553d4c39686605d2625d6philippe   XArray* /* of TempVar* */ dioff_lookup_tab;
4374c9831572483ed485438553d4c39686605d2625d6philippe   Int pass;
4375c9831572483ed485438553d4c39686605d2625d6philippe   VgHashTable signature_types = NULL;
4376c9831572483ed485438553d4c39686605d2625d6philippe
4377c9831572483ed485438553d4c39686605d2625d6philippe   /* Display/trace various information, if requested. */
4378e0bd5910153720d5d15697db8063d0d4caa59d8fphilippe   if (TD3) {
4379c9831572483ed485438553d4c39686605d2625d6philippe      trace_debug_loc    (di, barf, escn_debug_loc);
4380c9831572483ed485438553d4c39686605d2625d6philippe      trace_debug_ranges (di, barf, escn_debug_ranges);
4381c9831572483ed485438553d4c39686605d2625d6philippe      trace_debug_abbrev (di, barf, escn_debug_abbv);
4382c9831572483ed485438553d4c39686605d2625d6philippe      TRACE_SYMTAB("\n");
4383c9831572483ed485438553d4c39686605d2625d6philippe   }
4384c9831572483ed485438553d4c39686605d2625d6philippe
43855612d1a3bcfb43437890c6a27396b839b7c24ef9philippe   /* Zero out all parsers. Parsers will really be initialised
43865612d1a3bcfb43437890c6a27396b839b7c24ef9philippe      according to VG_(clo_read_*_info). */
43875612d1a3bcfb43437890c6a27396b839b7c24ef9philippe   VG_(memset)( &varparser, 0, sizeof(varparser) );
43885612d1a3bcfb43437890c6a27396b839b7c24ef9philippe   VG_(memset)( &inlparser, 0, sizeof(inlparser) );
43895612d1a3bcfb43437890c6a27396b839b7c24ef9philippe   VG_(memset)( &typarser, 0, sizeof(typarser) );
4390b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4391a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (VG_(clo_read_var_info)) {
4392a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* We'll park the harvested type information in here.  Also create
4393a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         a fake "void" entry with offset D3_FAKEVOID_CUOFF, so we always
4394a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         have at least one type entry to refer to.  D3_FAKEVOID_CUOFF is
4395a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         huge and presumably will not occur in any valid DWARF3 file --
4396a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         it would need to have a .debug_info section 4GB long for that to
4397a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         happen.  These type entries end up in the DebugInfo. */
4398a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      tyents = VG_(newXA)( ML_(dinfo_zalloc),
4399a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                           "di.readdwarf3.ndrw.1 (TyEnt temp array)",
4400a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                           ML_(dinfo_free), sizeof(TyEnt) );
4401a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      { TyEnt tyent;
4402a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe        VG_(memset)(&tyent, 0, sizeof(tyent));
4403a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe        tyent.tag   = Te_TyVoid;
4404a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe        tyent.cuOff = D3_FAKEVOID_CUOFF;
4405a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe        tyent.Te.TyVoid.isFake = True;
4406a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe        VG_(addToXA)( tyents, &tyent );
4407a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
4408a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      { TyEnt tyent;
4409a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe        VG_(memset)(&tyent, 0, sizeof(tyent));
4410a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe        tyent.tag   = Te_UNKNOWN;
4411a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe        tyent.cuOff = D3_INVALID_CUOFF;
4412a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe        VG_(addToXA)( tyents, &tyent );
4413a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
4414a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4415a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* This is a tree used to unique-ify the range lists that are
4416a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         manufactured by parse_var_DIE.  References to the keys in the
4417a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         tree wind up in .rngMany fields in TempVars.  We'll need to
4418a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         delete this tree, and the XArrays attached to it, at the end of
4419a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         this function. */
4420a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      rangestree = VG_(newFM)( ML_(dinfo_zalloc),
4421a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                               "di.readdwarf3.ndrw.2 (rangestree)",
4422a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                               ML_(dinfo_free),
4423a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                               (Word(*)(UWord,UWord))cmp__XArrays_of_AddrRange );
4424a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4425a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* List of variables we're accumulating.  These don't end up in the
4426a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         DebugInfo; instead their contents are handed to ML_(addVar) and
4427a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         the list elements are then deleted. */
4428a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      tempvars = VG_(newXA)( ML_(dinfo_zalloc),
4429a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             "di.readdwarf3.ndrw.3 (TempVar*s array)",
4430a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             ML_(dinfo_free),
4431a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             sizeof(TempVar*) );
4432a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4433a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* List of GExprs we're accumulating.  These wind up in the
4434a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         DebugInfo. */
4435a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      gexprs = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.4",
4436a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                           ML_(dinfo_free), sizeof(GExpr*) );
4437a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4438a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* We need a D3TypeParser to keep track of partially constructed
4439a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         types.  It'll be discarded as soon as we've completed the CU,
4440a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         since the resulting information is tipped in to 'tyents' as it
4441a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         is generated. */
4442a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      typarser.sp = -1;
4443a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      typarser.language = '?';
4444a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      for (i = 0; i < N_D3_TYPE_STACK; i++) {
4445a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         typarser.qparentE[i].tag   = Te_EMPTY;
4446a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         typarser.qparentE[i].cuOff = D3_INVALID_CUOFF;
4447a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
44489c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
4449a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      varparser.sp = -1;
4450a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4451a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      signature_types = VG_(HT_construct) ("signature_types");
44529c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   }
4453b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4454d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   /* Do an initial pass to scan the .debug_types section, if any, and
4455d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      fill in the signatured types hash table.  This lets us handle
4456d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      mapping from a type signature to a (cooked) DIE offset directly
4457d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      in get_Form_contents.  */
4458a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (VG_(clo_read_var_info) && ML_(sli_is_valid)(escn_debug_types)) {
44595d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      init_Cursor( &info, escn_debug_types, 0, barf,
4460d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                   "Overrun whilst reading .debug_types section" );
44615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      TRACE_D3("\n------ Collecting signatures from "
44625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               ".debug_types section ------\n");
4463b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4464d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      while (True) {
4465d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         UWord   cu_start_offset, cu_offset_now;
4466d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         CUConst cc;
4467d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4468d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cu_start_offset = get_position_of_Cursor( &info );
4469d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         TRACE_D3("\n");
4470d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         TRACE_D3("  Compilation Unit @ offset 0x%lx:\n", cu_start_offset);
4471746e97e7098def65d59c79d5d661f9a757a837cdphilippe         /* parse_CU_header initialises the CU's abbv hash table.  */
44725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         parse_CU_Header( &cc, td3, &info, escn_debug_abbv, True, False );
4473d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4474d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* Needed by cook_die.  */
44755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.types_cuOff_bias = escn_debug_info.szB;
4476d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4477d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         record_signatured_type( signature_types, cc.type_signature,
4478d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                                 cook_die( &cc, cc.type_offset ));
4479d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4480d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* Until proven otherwise we assume we don't need the icc9
4481d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            workaround in this case; see the DIE-reading loop below
4482d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            for details.  */
4483d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cu_offset_now = (cu_start_offset + cc.unit_length
4484d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                          + (cc.is_dw64 ? 12 : 4));
4485d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4486746e97e7098def65d59c79d5d661f9a757a837cdphilippe         if (cu_offset_now >= escn_debug_types.szB) {
4487746e97e7098def65d59c79d5d661f9a757a837cdphilippe            clear_CUConst ( &cc);
4488d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            break;
4489746e97e7098def65d59c79d5d661f9a757a837cdphilippe         }
4490d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4491d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         set_position_of_Cursor ( &info, cu_offset_now );
4492b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4493d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj   }
4494d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4495f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   /* Perform three DIE-reading passes.  The first pass reads DIEs from
4496f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      alternate .debug_info (if any), the second pass reads DIEs from
4497f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      .debug_info, and the third pass reads DIEs from .debug_types.
4498d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      Moving the body of this loop into a separate function would
4499d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      require a large number of arguments to be passed in, so it is
4500d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      kept inline instead.  */
4501f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj   for (pass = 0; pass < 3; ++pass) {
45025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      ULong section_size;
4503d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4504d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      if (pass == 0) {
45055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (!ML_(sli_is_valid)(escn_debug_info_alt))
4506f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj	    continue;
4507f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         /* Now loop over the Compilation Units listed in the alternate
4508f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            .debug_info section (see D3SPEC sec 7.5) paras 1 and 2.
4509f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            Each compilation unit contains a Compilation Unit Header
4510f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            followed by precisely one DW_TAG_compile_unit or
4511f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            DW_TAG_partial_unit DIE. */
45125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         init_Cursor( &info, escn_debug_info_alt, 0, barf,
4513f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                      "Overrun whilst reading alternate .debug_info section" );
45145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         section_size = escn_debug_info_alt.szB;
4515f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj
4516f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj         TRACE_D3("\n------ Parsing alternate .debug_info section ------\n");
4517f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj      } else if (pass == 1) {
4518d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* Now loop over the Compilation Units listed in the .debug_info
4519d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            section (see D3SPEC sec 7.5) paras 1 and 2.  Each compilation
4520d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            unit contains a Compilation Unit Header followed by precisely
4521d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            one DW_TAG_compile_unit or DW_TAG_partial_unit DIE. */
45225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         init_Cursor( &info, escn_debug_info, 0, barf,
4523d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                      "Overrun whilst reading .debug_info section" );
45245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         section_size = escn_debug_info.szB;
4525d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4526d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         TRACE_D3("\n------ Parsing .debug_info section ------\n");
4527d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      } else {
45285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (!ML_(sli_is_valid)(escn_debug_types))
4529d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            continue;
4530e504887521dfee904f4dcea3655515bc99a6801fphilippe         if (!VG_(clo_read_var_info))
4531e504887521dfee904f4dcea3655515bc99a6801fphilippe            continue; // Types not needed when only reading inline info.
45325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         init_Cursor( &info, escn_debug_types, 0, barf,
4533d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                      "Overrun whilst reading .debug_types section" );
45345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         section_size = escn_debug_types.szB;
4535d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4536d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         TRACE_D3("\n------ Parsing .debug_types section ------\n");
4537b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
4538b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4539d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      while (True) {
45405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong   cu_start_offset, cu_offset_now;
4541d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         CUConst cc;
4542d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* It may be that the stated size of this CU is larger than the
4543d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            amount of stuff actually in it.  icc9 seems to generate CUs
4544d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            thusly.  We use these variables to figure out if this is
4545d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            indeed the case, and if so how many bytes we need to skip to
4546d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            get to the start of the next CU.  Not skipping those bytes
4547d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            causes us to misidentify the start of the next CU, and it all
4548d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            goes badly wrong after that (not surprisingly). */
4549d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         UWord cu_size_including_IniLen, cu_amount_used;
4550d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4551d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* It seems icc9 finishes the DIE info before debug_info_sz
4552d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            bytes have been used up.  So be flexible, and declare the
4553d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            sequence complete if there is not enough remaining bytes to
4554d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            hold even the smallest conceivable CU header.  (11 bytes I
4555d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            reckon). */
4556d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* JRS 23Jan09: I suspect this is no longer necessary now that
4557d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            the code below contains a 'while (cu_amount_used <
4558d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            cu_size_including_IniLen ...'  style loop, which skips over
4559d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            any leftover bytes at the end of a CU in the case where the
4560d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            CU's stated size is larger than its actual size (as
4561d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            determined by reading all its DIEs).  However, for prudence,
4562d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            I'll leave the following test in place.  I can't see that a
4563d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            CU header can be smaller than 11 bytes, so I don't think
4564d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            there's any harm possible through the test -- it just adds
4565d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            robustness. */
4566d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         Word avail = get_remaining_length_Cursor( &info );
4567d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         if (avail < 11) {
4568d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            if (avail > 0)
4569d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj               TRACE_D3("new_dwarf3_reader_wrk: warning: "
4570d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                        "%ld unused bytes after end of DIEs\n", avail);
4571d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            break;
4572d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         }
4573d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4574a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (VG_(clo_read_var_info)) {
4575a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            /* Check the varparser's stack is in a sane state. */
4576a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            vg_assert(varparser.sp == -1);
4577a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            for (i = 0; i < N_D3_VAR_STACK; i++) {
4578a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               vg_assert(varparser.ranges[i] == NULL);
4579a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               vg_assert(varparser.level[i] == 0);
4580a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            }
4581a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            for (i = 0; i < N_D3_TYPE_STACK; i++) {
4582a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               vg_assert(typarser.qparentE[i].cuOff == D3_INVALID_CUOFF);
4583a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               vg_assert(typarser.qparentE[i].tag   == Te_EMPTY);
4584a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               vg_assert(typarser.qlevel[i] == 0);
4585a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            }
4586d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         }
4587d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4588d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cu_start_offset = get_position_of_Cursor( &info );
4589d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         TRACE_D3("\n");
45905d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         TRACE_D3("  Compilation Unit @ offset 0x%llx:\n", cu_start_offset);
45910d2ea9d1cfd6f1fff0992096c2d15881becfe2e1philippe         /* parse_CU_header initialises the CU's hashtable of abbvs ht_abbvs */
45925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (pass == 0) {
45935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            parse_CU_Header( &cc, td3, &info, escn_debug_abbv_alt,
4594f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                             False, True );
45955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         } else {
45965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            parse_CU_Header( &cc, td3, &info, escn_debug_abbv,
4597f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj                             pass == 2, False );
45985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
45995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_str      = pass == 0 ? escn_debug_str_alt
46005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                            : escn_debug_str;
46015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_ranges   = escn_debug_ranges;
46025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_loc      = escn_debug_loc;
46035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_line     = pass == 0 ? escn_debug_line_alt
46045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                            : escn_debug_line;
46055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_info     = pass == 0 ? escn_debug_info_alt
46065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                            : escn_debug_info;
46075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_types    = escn_debug_types;
46085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_info_alt = escn_debug_info_alt;
46095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.escn_debug_str_alt  = escn_debug_str_alt;
46105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.types_cuOff_bias    = escn_debug_info.szB;
46115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.alt_cuOff_bias      = escn_debug_info.szB + escn_debug_types.szB;
46125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cc.cu_start_offset     = cu_start_offset;
4613d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cc.di = di;
4614d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* The CU's svma can be deduced by looking at the AT_low_pc
4615d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            value in the top level TAG_compile_unit, which is the topmost
4616d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            DIE.  We'll leave it for the 'varparser' to acquire that info
4617d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            and fill it in -- since it is the only party to want to know
4618d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            it. */
4619d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cc.cu_svma_known = False;
4620d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cc.cu_svma       = 0;
4621d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4622a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (VG_(clo_read_var_info)) {
4623a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            cc.signature_types = signature_types;
4624a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4625a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            /* Create a fake outermost-level range covering the entire
4626a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               address range.  So we always have *something* to catch all
4627a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               variable declarations. */
4628a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            varstack_push( &cc, &varparser, td3,
4629a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                           unitary_range_list(0UL, ~0UL),
4630a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                           -1, False/*isFunc*/, NULL/*fbGX*/ );
4631a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4632666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            /* And set up the fndn_ix_Table.  When we come across the top
4633a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               level DIE for this CU (which is what the next call to
4634a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               read_DIE should process) we will copy all the file names out
4635a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               of the .debug_line img area and use this table to look up the
4636a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               copies when we later see filename numbers in DW_TAG_variables
4637a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               etc. */
4638666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            vg_assert(!varparser.fndn_ix_Table );
4639666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            varparser.fndn_ix_Table
4640a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.5var",
4641a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             ML_(dinfo_free),
4642666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                             sizeof(UInt) );
4643666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            vg_assert(varparser.fndn_ix_Table);
4644a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
4645a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4646a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (VG_(clo_read_inline_info)) {
4647666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            /* fndn_ix_Table for the inlined call parser */
4648666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            vg_assert(!inlparser.fndn_ix_Table );
4649666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            inlparser.fndn_ix_Table
4650a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.5inl",
4651a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                             ML_(dinfo_free),
4652666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                             sizeof(UInt) );
4653666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            vg_assert(inlparser.fndn_ix_Table);
4654a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
4655d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4656d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* Now read the one-and-only top-level DIE for this CU. */
4657a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         vg_assert(!VG_(clo_read_var_info) || varparser.sp == 0);
4658d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         read_DIE( rangestree,
4659d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                   tyents, tempvars, gexprs,
4660a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                   &typarser, &varparser, &inlparser,
4661d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                   &info, td3, &cc, 0 );
4662d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4663055b0f85aaa42477a803d445885c389561d3d3c8sewardj         cu_offset_now = get_position_of_Cursor( &info );
4664055b0f85aaa42477a803d445885c389561d3d3c8sewardj
46655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (0) VG_(printf)("Travelled: %llu  size %llu\n",
4666d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                            cu_offset_now - cc.cu_start_offset,
4667d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                            cc.unit_length + (cc.is_dw64 ? 12 : 4));
46684bad5933e7b59ab9c756fb71da0f7fea7c4e61f0philippe
4669d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* How big the CU claims it is .. */
4670d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cu_size_including_IniLen = cc.unit_length + (cc.is_dw64 ? 12 : 4);
4671d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* .. vs how big we have found it to be */
4672d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         cu_amount_used = cu_offset_now - cc.cu_start_offset;
4673b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
46745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (1) TRACE_D3("offset now %lld, d-i-size %lld\n",
4675d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                         cu_offset_now, section_size);
4676d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         if (cu_offset_now > section_size)
4677d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            barf("toplevel DIEs beyond end of CU");
4678d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4679d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* If the CU is bigger than it claims to be, we've got a serious
4680d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            problem. */
4681d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         if (cu_amount_used > cu_size_including_IniLen)
4682d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            barf("CU's actual size appears to be larger than it claims it is");
4683d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4684d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* If the CU is smaller than it claims to be, we need to skip some
4685d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            bytes.  Loop updates cu_offset_new and cu_amount_used. */
4686d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         while (cu_amount_used < cu_size_including_IniLen
4687d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj                && get_remaining_length_Cursor( &info ) > 0) {
4688d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            if (0) VG_(printf)("SKIP\n");
4689d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            (void)get_UChar( &info );
4690d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            cu_offset_now = get_position_of_Cursor( &info );
4691d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            cu_amount_used = cu_offset_now - cc.cu_start_offset;
4692d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         }
4693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4694a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (VG_(clo_read_var_info)) {
4695a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            /* Preen to level -2.  DIEs have level >= 0 so -2 cannot occur
4696a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               anywhere else at all.  Our fake the-entire-address-space
4697a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               range is at level -1, so preening to -2 should completely
4698a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               empty the stack out. */
4699a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            TRACE_D3("\n");
4700a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            varstack_preen( &varparser, td3, -2 );
4701a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            /* Similarly, empty the type stack out. */
4702a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            typestack_preen( &typarser, td3, -2 );
4703a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
4704d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4705a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (VG_(clo_read_var_info)) {
4706666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            vg_assert(varparser.fndn_ix_Table );
4707666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            VG_(deleteXA)( varparser.fndn_ix_Table );
4708666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            varparser.fndn_ix_Table = NULL;
4709a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
4710a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (VG_(clo_read_inline_info)) {
4711666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            vg_assert(inlparser.fndn_ix_Table );
4712666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            VG_(deleteXA)( inlparser.fndn_ix_Table );
4713666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            inlparser.fndn_ix_Table = NULL;
4714a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
4715746e97e7098def65d59c79d5d661f9a757a837cdphilippe         clear_CUConst(&cc);
4716d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
4717d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         if (cu_offset_now == section_size)
4718d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj            break;
4719d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj         /* else keep going */
4720d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj      }
4721b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
4722b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4723b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4724a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   if (VG_(clo_read_var_info)) {
4725a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* From here on we're post-processing the stuff we got
4726a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         out of the .debug_info section. */
4727e0bd5910153720d5d15697db8063d0d4caa59d8fphilippe      if (TD3) {
4728a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         TRACE_D3("\n");
4729a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ML_(pp_TyEnts)(tyents, "Initial type entity (TyEnt) array");
4730a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         TRACE_D3("\n");
4731a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         TRACE_D3("------ Compressing type entries ------\n");
4732a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
4733a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4734a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      tyents_cache = ML_(dinfo_zalloc)( "di.readdwarf3.ndrw.6",
4735a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                                        sizeof(TyEntIndexCache) );
4736a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      ML_(TyEntIndexCache__invalidate)( tyents_cache );
4737a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      dedup_types( td3, tyents, tyents_cache );
4738e0bd5910153720d5d15697db8063d0d4caa59d8fphilippe      if (TD3) {
4739a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         TRACE_D3("\n");
4740a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ML_(pp_TyEnts)(tyents, "After type entity (TyEnt) compression");
4741a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
4742a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
47439c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      TRACE_D3("\n");
4744a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      TRACE_D3("------ Resolving the types of variables ------\n" );
4745a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      resolve_variable_types( barf, tyents, tyents_cache, tempvars );
47469c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
4747a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Copy all the non-INDIR tyents into a new table.  For large
4748a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         .so's, about 90% of the tyents will by now have been resolved to
4749a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         INDIRs, and we no longer need them, and so don't need to store
4750a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         them. */
4751a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      tyents_to_keep
4752a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         = VG_(newXA)( ML_(dinfo_zalloc),
4753a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                       "di.readdwarf3.ndrw.7 (TyEnt to-keep array)",
4754a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                       ML_(dinfo_free), sizeof(TyEnt) );
4755a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      n = VG_(sizeXA)( tyents );
4756a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      for (i = 0; i < n; i++) {
4757a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         TyEnt* ent = VG_(indexXA)( tyents, i );
4758a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (ent->tag != Te_INDIR)
4759a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            VG_(addToXA)( tyents_to_keep, ent );
4760a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
47619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
4762a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(deleteXA)( tyents );
4763a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      tyents = NULL;
4764a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      ML_(dinfo_free)( tyents_cache );
4765a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      tyents_cache = NULL;
4766a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4767a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Sort tyents_to_keep so we can lookup in it.  A complete (if
4768a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         minor) waste of time, since tyents itself is sorted, but
4769a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         necessary since VG_(lookupXA) refuses to cooperate if we
4770a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         don't. */
4771a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(setCmpFnXA)( tyents_to_keep, (XACmpFn_t) ML_(TyEnt__cmp_by_cuOff_only) );
4772a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(sortXA)( tyents_to_keep );
4773a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4774a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Enable cacheing on tyents_to_keep */
4775a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      tyents_to_keep_cache
4776a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         = ML_(dinfo_zalloc)( "di.readdwarf3.ndrw.8",
4777a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                              sizeof(TyEntIndexCache) );
4778a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      ML_(TyEntIndexCache__invalidate)( tyents_to_keep_cache );
4779a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4780a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* And record the tyents in the DebugInfo.  We do this before
4781a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         starting to hand variables to ML_(addVar), since if ML_(addVar)
4782a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         wants to do debug printing (of the types of said vars) then it
4783a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         will need the tyents.*/
4784a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      vg_assert(!di->admin_tyents);
4785a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      di->admin_tyents = tyents_to_keep;
4786a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4787a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Bias all the location expressions. */
4788a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      TRACE_D3("\n");
4789a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      TRACE_D3("------ Biasing the location expressions ------\n" );
479068a2ebd9384661a85a4674fe8310c595ad494305sewardj
4791a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      n = VG_(sizeXA)( gexprs );
4792a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      for (i = 0; i < n; i++) {
4793a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         gexpr = *(GExpr**)VG_(indexXA)( gexprs, i );
4794a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         bias_GX( gexpr, di );
4795a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
4796b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4797a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      TRACE_D3("\n");
4798a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      TRACE_D3("------ Acquired the following variables: ------\n\n");
4799a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4800a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Park (pointers to) all the vars in an XArray, so we can look up
4801a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         abstract origins quickly.  The array is sorted (hence, looked-up
4802a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         by) the .dioff fields.  Since the .dioffs should be in strictly
4803a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ascending order, there is no need to sort the array after
4804a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         construction.  The ascendingness is however asserted for. */
4805a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      dioff_lookup_tab
4806a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.9",
4807a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                       ML_(dinfo_free),
4808a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                       sizeof(TempVar*) );
4809a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      vg_assert(dioff_lookup_tab);
4810a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4811a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      n = VG_(sizeXA)( tempvars );
4812a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      Word first_primary_var = 0;
4813a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      for (first_primary_var = 0;
4814a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           escn_debug_info_alt.szB/*really?*/ && first_primary_var < n;
4815a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           first_primary_var++) {
4816a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         varp = *(TempVar**)VG_(indexXA)( tempvars, first_primary_var );
4817a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (varp->dioff < escn_debug_info.szB + escn_debug_types.szB)
4818a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            break;
481959a2d18d0ddfa241850017252b0804d469187d79sewardj      }
4820a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      for (i = 0; i < n; i++) {
4821a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         varp = *(TempVar**)VG_(indexXA)( tempvars, (i + first_primary_var) % n );
4822a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (i > first_primary_var) {
4823a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            varp2 = *(TempVar**)VG_(indexXA)( tempvars,
4824a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                                              (i + first_primary_var - 1) % n );
4825a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            /* why should this hold?  Only, I think, because we've
4826a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               constructed the array by reading .debug_info sequentially,
4827a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               and so the array .dioff fields should reflect that, and be
4828a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               strictly ascending. */
4829a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            vg_assert(varp2->dioff < varp->dioff);
4830a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
4831a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         VG_(addToXA)( dioff_lookup_tab, &varp );
4832a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
4833a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(setCmpFnXA)( dioff_lookup_tab, cmp_TempVar_by_dioff );
4834a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(sortXA)( dioff_lookup_tab ); /* POINTLESS; FIXME: rm */
4835b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4836a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Now visit each var.  Collect up as much info as possible for
4837a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         each var and hand it to ML_(addVar). */
4838a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      n = VG_(sizeXA)( tempvars );
4839a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      for (j = 0; j < n; j++) {
4840a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         TyEnt* ent;
4841a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         varp = *(TempVar**)VG_(indexXA)( tempvars, j );
4842b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4843a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* Possibly show .. */
4844e0bd5910153720d5d15697db8063d0d4caa59d8fphilippe         if (TD3) {
4845a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            VG_(printf)("<%lx> addVar: level %d: %s :: ",
4846a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        varp->dioff,
4847a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        varp->level,
4848a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        varp->name ? varp->name : "<anon_var>" );
4849a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (varp->typeR) {
4850a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               ML_(pp_TyEnt_C_ishly)( tyents_to_keep, varp->typeR );
4851a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            } else {
4852a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               VG_(printf)("NULL");
4853a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            }
4854a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            VG_(printf)("\n  Loc=");
4855a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (varp->gexpr) {
4856a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               ML_(pp_GX)(varp->gexpr);
4857a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            } else {
4858a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               VG_(printf)("NULL");
4859a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            }
4860b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            VG_(printf)("\n");
4861a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (varp->fbGX) {
4862a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               VG_(printf)("  FrB=");
4863a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               ML_(pp_GX)( varp->fbGX );
4864a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               VG_(printf)("\n");
4865a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            } else {
4866a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               VG_(printf)("  FrB=none\n");
4867a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            }
4868666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            VG_(printf)("  declared at: %d %s:%d\n",
4869666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                        varp->fndn_ix,
4870666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                        ML_(fndn_ix2filename) (di, varp->fndn_ix),
4871a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                        varp->fLine );
4872a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (varp->absOri != (UWord)D3_INVALID_CUOFF)
4873a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               VG_(printf)("  abstract origin: <%lx>\n", varp->absOri);
4874b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         }
4875b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4876a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* Skip variables which have no location.  These must be
4877a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            abstract instances; they are useless as-is since with no
4878a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            location they have no specified memory location.  They will
4879a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            presumably be referred to via the absOri fields of other
4880a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            variables. */
4881a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (!varp->gexpr) {
4882a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            TRACE_D3("  SKIP (no location)\n\n");
4883bdee918842b4b2d4a09146a4642e999dc71b3652sewardj            continue;
4884bdee918842b4b2d4a09146a4642e999dc71b3652sewardj         }
4885b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
4886a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* So it has a location, at least.  If it refers to some other
4887a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            entry through its absOri field, pull in further info through
4888a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            that. */
4889a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (varp->absOri != (UWord)D3_INVALID_CUOFF) {
4890a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            Bool found;
4891a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            Word ixFirst, ixLast;
4892a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            TempVar key;
4893a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            TempVar* keyp = &key;
4894a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            TempVar *varAI;
4895a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            VG_(memset)(&key, 0, sizeof(key)); /* not necessary */
4896a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            key.dioff = varp->absOri; /* this is what we want to find */
4897a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            found = VG_(lookupXA)( dioff_lookup_tab, &keyp,
4898a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                                   &ixFirst, &ixLast );
4899a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (!found) {
4900a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               /* barf("DW_AT_abstract_origin can't be resolved"); */
4901a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               TRACE_D3("  SKIP (DW_AT_abstract_origin can't be resolved)\n\n");
4902a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               continue;
4903a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            }
4904a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            /* If the following fails, there is more than one entry with
4905a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               the same dioff.  Which can't happen. */
4906a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            vg_assert(ixFirst == ixLast);
4907a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            varAI = *(TempVar**)VG_(indexXA)( dioff_lookup_tab, ixFirst );
4908a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            /* stay sane */
4909a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            vg_assert(varAI);
4910a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            vg_assert(varAI->dioff == varp->absOri);
4911a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4912a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            /* Copy what useful info we can. */
4913a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (varAI->typeR && !varp->typeR)
4914a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               varp->typeR = varAI->typeR;
4915a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (varAI->name && !varp->name)
4916a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               varp->name = varAI->name;
4917666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe            if (varAI->fndn_ix && !varp->fndn_ix)
4918666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe               varp->fndn_ix = varAI->fndn_ix;
4919a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            if (varAI->fLine > 0 && varp->fLine == 0)
4920a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe               varp->fLine = varAI->fLine;
4921a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
4922a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4923a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* Give it a name if it doesn't have one. */
4924a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (!varp->name)
4925a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            varp->name = ML_(addStr)( di, "<anon_var>", -1 );
4926a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4927a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* So now does it have enough info to be useful? */
4928a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* NOTE: re typeR: this is a hack.  If typeR is Te_UNKNOWN then
4929a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            the type didn't get resolved.  Really, in that case
4930a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            something's broken earlier on, and should be fixed, rather
4931a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            than just skipping the variable. */
4932a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ent = ML_(TyEnts__index_by_cuOff)( tyents_to_keep,
4933a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                                            tyents_to_keep_cache,
4934a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                                            varp->typeR );
4935a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* The next two assertions should be guaranteed by
4936a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            our previous call to resolve_variable_types. */
4937a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         vg_assert(ent);
4938a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         vg_assert(ML_(TyEnt__is_type)(ent) || ent->tag == Te_UNKNOWN);
4939a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4940a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         if (ent->tag == Te_UNKNOWN) continue;
4941a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4942a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         vg_assert(varp->gexpr);
4943a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         vg_assert(varp->name);
4944a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         vg_assert(varp->typeR);
4945a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         vg_assert(varp->level >= 0);
4946a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4947a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* Ok.  So we're going to keep it.  Call ML_(addVar) once for
4948a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe            each address range in which the variable exists. */
4949a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         TRACE_D3("  ACQUIRE for range(s) ");
4950a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         { AddrRange  oneRange;
4951a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           AddrRange* varPcRanges;
4952a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           Word       nVarPcRanges;
4953a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           /* Set up to iterate over address ranges, however
4954a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              represented. */
4955a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           if (varp->nRanges == 0 || varp->nRanges == 1) {
4956a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              vg_assert(!varp->rngMany);
4957a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              if (varp->nRanges == 0) {
4958a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 vg_assert(varp->rngOneMin == 0);
4959a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 vg_assert(varp->rngOneMax == 0);
4960a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              }
4961a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              nVarPcRanges = varp->nRanges;
4962a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              oneRange.aMin = varp->rngOneMin;
4963a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              oneRange.aMax = varp->rngOneMax;
4964a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              varPcRanges = &oneRange;
4965a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           } else {
4966a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              vg_assert(varp->rngMany);
4967b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              vg_assert(varp->rngOneMin == 0);
4968b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj              vg_assert(varp->rngOneMax == 0);
4969a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              nVarPcRanges = VG_(sizeXA)(varp->rngMany);
4970a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              vg_assert(nVarPcRanges >= 2);
4971a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              vg_assert(nVarPcRanges == (Word)varp->nRanges);
4972a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              varPcRanges = VG_(indexXA)(varp->rngMany, 0);
4973b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           }
4974a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           if (varp->level == 0)
4975a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              vg_assert( nVarPcRanges == 1 );
4976a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           /* and iterate */
4977a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe           for (i = 0; i < nVarPcRanges; i++) {
4978a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              Addr pcMin = varPcRanges[i].aMin;
4979a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              Addr pcMax = varPcRanges[i].aMax;
4980a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              vg_assert(pcMin <= pcMax);
4981a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              /* Level 0 is the global address range.  So at level 0 we
4982a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 don't want to bias pcMin/pcMax; but at all other levels
4983a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 we do since those are derived from svmas in the Dwarf
4984a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 we're reading.  Be paranoid ... */
4985a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              if (varp->level == 0) {
4986a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 vg_assert(pcMin == (Addr)0);
4987a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 vg_assert(pcMax == ~(Addr)0);
4988a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              } else {
4989a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 /* vg_assert(pcMin > (Addr)0);
4990a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                    No .. we can legitimately expect to see ranges like
4991a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                    0x0-0x11D (pre-biasing, of course). */
4992a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 vg_assert(pcMax < ~(Addr)0);
4993a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              }
4994a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
4995a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              /* Apply text biasing, for non-global variables. */
4996a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              if (varp->level > 0) {
4997a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 pcMin += di->text_debug_bias;
4998a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 pcMax += di->text_debug_bias;
4999a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              }
5000a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
5001a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              if (i > 0 && (i%2) == 0)
5002a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 TRACE_D3("\n                       ");
5003a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              TRACE_D3("[%#lx,%#lx] ", pcMin, pcMax );
5004a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe
5005a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              ML_(addVar)(
5006a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                 di, varp->level,
5007a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     pcMin, pcMax,
5008a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     varp->name,  varp->typeR,
5009a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe                     varp->gexpr, varp->fbGX,
5010666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe                     varp->fndn_ix, varp->fLine, td3
5011a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe              );
5012b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           }
5013a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         }
5014b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5015a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         TRACE_D3("\n\n");
5016a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         /* and move on to the next var */
5017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
5018b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5019a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* Now free all the TempVars */
5020a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      n = VG_(sizeXA)( tempvars );
5021a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      for (i = 0; i < n; i++) {
5022a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         varp = *(TempVar**)VG_(indexXA)( tempvars, i );
5023a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         ML_(dinfo_free)(varp);
5024a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      }
5025a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(deleteXA)( tempvars );
5026a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      tempvars = NULL;
5027b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5028a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* and the temp lookup table */
5029a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(deleteXA)( dioff_lookup_tab );
5030b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5031a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* and the ranges tree.  Note that we need to also free the XArrays
5032a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         which constitute the keys, hence pass VG_(deleteXA) as a
5033a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe         key-finalizer. */
5034a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(deleteFM)( rangestree, (void(*)(UWord))VG_(deleteXA), NULL );
50359c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
5036a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* and the tyents_to_keep cache */
5037a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      ML_(dinfo_free)( tyents_to_keep_cache );
5038a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      tyents_to_keep_cache = NULL;
50399c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
5040666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe      vg_assert( varparser.fndn_ix_Table == NULL );
5041d935068fc7b53c8a826b3436cdfccd5b7d446903sewardj
5042a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* And the signatured type hash.  */
5043a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      VG_(HT_destruct) ( signature_types, ML_(dinfo_free) );
50449c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj
5045a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      /* record the GExprs in di so they can be freed later */
5046a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      vg_assert(!di->admin_gexprs);
5047a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe      di->admin_gexprs = gexprs;
5048a0a73939b0398b6608fd6dbde49820ce6530d12cphilippe   }
5049b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5051b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5052b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
5053b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
5054b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--- The "new" DWARF3 reader -- top level control logic   ---*/
5055b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*---                                                      ---*/
5056b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*------------------------------------------------------------*/
5057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
50586c591e15c1d6402a2a755310f005f795b68e7e38sewardjstatic Bool               d3rd_jmpbuf_valid  = False;
50596bd9dc18c043927c1196caba20a327238a179c42florianstatic const HChar*       d3rd_jmpbuf_reason = NULL;
506097d3ebba515c00930db4ee3f52af571bc84b2ef6sewardjstatic VG_MINIMAL_JMP_BUF(d3rd_jmpbuf);
5061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
50626bd9dc18c043927c1196caba20a327238a179c42florianstatic __attribute__((noreturn)) void barf ( const HChar* reason ) {
5063b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(d3rd_jmpbuf_valid);
5064b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   d3rd_jmpbuf_reason = reason;
50656c591e15c1d6402a2a755310f005f795b68e7e38sewardj   VG_MINIMAL_LONGJMP(d3rd_jmpbuf);
5066b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /*NOTREACHED*/
5067b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(0);
5068b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5069b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5070b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5071b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid
5072b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjML_(new_dwarf3_reader) (
5073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   struct _DebugInfo* di,
50745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_info,      DiSlice escn_debug_types,
50755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_abbv,      DiSlice escn_debug_line,
50765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_str,       DiSlice escn_debug_ranges,
50775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_loc,       DiSlice escn_debug_info_alt,
50785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_abbv_alt,  DiSlice escn_debug_line_alt,
50795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiSlice escn_debug_str_alt
5080b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj)
5081b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj{
5082b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   volatile Int  jumped;
5083b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   volatile Bool td3 = di->trace_symtab;
5084b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5085b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Run the _wrk function to read the dwarf3.  If it succeeds, it
5086b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      just returns normally.  If there is any failure, it longjmp's
5087b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      back here, having first set d3rd_jmpbuf_reason to something
5088b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      useful. */
5089b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(d3rd_jmpbuf_valid  == False);
5090b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   vg_assert(d3rd_jmpbuf_reason == NULL);
5091b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5092b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   d3rd_jmpbuf_valid = True;
50936c591e15c1d6402a2a755310f005f795b68e7e38sewardj   jumped = VG_MINIMAL_SETJMP(d3rd_jmpbuf);
5094b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (jumped == 0) {
5095b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* try this ... */
5096b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      new_dwarf3_reader_wrk( di, barf,
50975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             escn_debug_info,     escn_debug_types,
50985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             escn_debug_abbv,     escn_debug_line,
50995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             escn_debug_str,      escn_debug_ranges,
51005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             escn_debug_loc,      escn_debug_info_alt,
51015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             escn_debug_abbv_alt, escn_debug_line_alt,
51025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             escn_debug_str_alt );
5103b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      d3rd_jmpbuf_valid = False;
5104b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("\n------ .debug_info reading was successful ------\n");
5105b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   } else {
5106b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* It longjmp'd. */
5107b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      d3rd_jmpbuf_valid = False;
5108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Can't longjump without giving some sort of reason. */
5109b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      vg_assert(d3rd_jmpbuf_reason != NULL);
5110b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("\n------ .debug_info reading failed ------\n");
5112b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ML_(symerr)(di, True, d3rd_jmpbuf_reason);
5114b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
5115b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5116b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   d3rd_jmpbuf_valid  = False;
5117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   d3rd_jmpbuf_reason = NULL;
5118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj}
5119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5120b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5121b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* --- Unused code fragments which might be useful one day. --- */
5123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5124b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#if 0
5125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   /* Read the arange tables */
5126b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n");
5127b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n------ The contents of .debug_arange ------\n");
5128b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   init_Cursor( &aranges, debug_aranges_img,
5129b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                debug_aranges_sz, 0, barf,
5130b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                "Overrun whilst reading .debug_aranges section" );
5131b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   while (True) {
5132b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ULong  len, d_i_offset;
5133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      Bool   is64;
5134b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UShort version;
5135b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      UChar  asize, segsize;
5136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5137b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (is_at_end_Cursor( &aranges ))
5138b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         break;
5139b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* Read one arange thingy */
5140b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      /* initial_length field */
5141b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      len = get_Initial_Length( &is64, &aranges,
5142b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj               "in .debug_aranges: invalid initial-length field" );
5143b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      version    = get_UShort( &aranges );
5144b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      d_i_offset = get_Dwarfish_UWord( &aranges, is64 );
5145b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      asize      = get_UChar( &aranges );
5146b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      segsize    = get_UChar( &aranges );
5147b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("  Length:                   %llu\n", len);
5148b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("  Version:                  %d\n", (Int)version);
5149b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("  Offset into .debug_info:  %llx\n", d_i_offset);
5150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("  Pointer Size:             %d\n", (Int)asize);
5151b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("  Segment Size:             %d\n", (Int)segsize);
5152b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("\n");
5153b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      TRACE_D3("    Address            Length\n");
5154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
5155b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while ((get_position_of_Cursor( &aranges ) % (2 * asize)) > 0) {
5156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         (void)get_UChar( & aranges );
5157b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
5158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      while (True) {
5159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ULong address = get_Dwarfish_UWord( &aranges, asize==8 );
5160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ULong length = get_Dwarfish_UWord( &aranges, asize==8 );
5161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         TRACE_D3("    0x%016llx 0x%llx\n", address, length);
5162b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (address == 0 && length == 0) break;
5163b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      }
5164b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   }
5165b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   TRACE_SYMTAB("\n");
5166b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#endif
5167b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj
51688b68b64759254d514d98328c496cbd88cde4c9a5njn#endif // defined(VGO_linux) || defined(VGO_darwin)
5169f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
5170b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------------*/
51718b68b64759254d514d98328c496cbd88cde4c9a5njn/*--- end                                                          ---*/
5172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/*--------------------------------------------------------------------*/
5173