1436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* -*- mode: C; c-basic-offset: 3; -*- */ 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Read DWARF3/4 ".debug_info" sections (DIE trees). ---*/ 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- readdwarf3.c ---*/ 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of Valgrind, a dynamic binary instrumentation 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown framework. 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 12436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Copyright (C) 2008-2013 OpenWorks LLP 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown info@open-works.co.uk 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is free software; you can redistribute it and/or 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify it under the terms of the GNU General Public License as 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown published by the Free Software Foundation; either version 2 of the 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown License, or (at your option) any later version. 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is distributed in the hope that it will be useful, but 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WITHOUT ANY WARRANTY; without even the implied warranty of 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown General Public License for more details. 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should have received a copy of the GNU General Public License 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown along with this program; if not, write to the Free Software 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 02111-1307, USA. 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The GNU General Public License is contained in the file COPYING. 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Neither the names of the U.S. Department of Energy nor the 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown University of California nor the names of its contributors may be 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown used to endorse or promote products derived from this software 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown without prior written permission. 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) || defined(VGO_darwin) 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* REFERENCE (without which this code will not make much sense): 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DWARF Debugging Information Format, Version 3, 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dated 20 December 2005 (the "D3 spec"). 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Available at http://www.dwarfstd.org/Dwarf3.pdf. There's also a 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .doc (MS Word) version, but for some reason the section numbers 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown between the Word and PDF versions differ by 1 in the first digit. 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown All section references in this code are to the PDF version. 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CURRENT HACKS: 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_TAG_{const,volatile}_type no DW_AT_type is allowed; it is 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown assumed to mean "const void" or "volatile void" respectively. 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GDB appears to interpret them like this, anyway. 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown In many cases it is important to know the svma of a CU (the "base 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown address of the CU", as the D3 spec calls it). There are some 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown situations in which the spec implies this value is unknown, but the 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Dwarf3 produced by gcc-4.1 seems to assume is not unknown but 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown merely zero when not explicitly stated. So we too have to make 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that assumption. 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown POTENTIAL BUG? Spotted 6 Sept 08. Why doesn't 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unitary_range_list() bias the resulting range list in the same way 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that its more general cousin, get_range_list(), does? I don't 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown know. 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TODO, 2008 Feb 17: 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown get rid of cu_svma_known and document the assumed-zero svma hack. 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(sizeOfType): differentiate between zero sized types and types 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for which the size is unknown. Is this important? I don't know. 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 75663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DW_TAG_array_types: deal with explicit sizes (currently we compute 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the size from the bounds and the element size, although that's 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fragile, if the bounds incompletely specified, or completely 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown absent) 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Document reason for difference (by 1) of stack preening depth in 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parse_var_DIE vs parse_type_DIE. 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Don't hand to ML_(addVars), vars whose locations are entirely in 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown registers (DW_OP_reg*). This is merely a space-saving 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown optimisation, as ML_(evaluate_Dwarf3_Expr) should handle these 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown expressions correctly, by failing to evaluate them and hence 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown effectively ignoring the variable with which they are associated. 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 89663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Deal with DW_TAG_array_types which have element size != stride 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown In some cases, the info for a variable is split between two 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown different DIEs (generally a declarer and a definer). We punt on 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown these. Could do better here. 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The 'data_bias' argument passed to the expression evaluator 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (ML_(evaluate_Dwarf3_Expr)) should really be changed to a 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MaybeUWord, to make it clear when we do vs don't know what it is 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for the evaluation of an expression. At the moment zero is passed 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for this parameter in the don't know case. That's a bit fragile 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and obscure; using a MaybeUWord would be clearer. 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown POTENTIAL PERFORMANCE IMPROVEMENTS: 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Currently, duplicate removal and all other queries for the type 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown entities array is done using cuOffset-based pointing, which 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown involves a binary search (VG_(lookupXA)) for each access. This is 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown wildly inefficient, although simple. It would be better to 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown translate all the cuOffset-based references (iow, all the "R" and 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "Rs" fields in the TyEnts in 'tyents') to direct index numbers in 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'tyents' right at the start of dedup_types(), and use direct 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown indexing (VG_(indexXA)) wherever possible after that. 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cmp__XArrays_of_AddrRange is also a performance bottleneck. Move 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(indexXA) into pub_tool_xarray.h so it can be inlined at all use 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown points, and possibly also make an _UNCHECKED version which skips 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the range checks in performance-critical situations such as this. 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Handle interaction between read_DIE and parse_{var,type}_DIE 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown better. Currently read_DIE reads the entire DIE just to find where 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the end is (and for debug printing), so that it can later reliably 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown move the cursor to the end regardless of what parse_{var,type}_DIE 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do. This means many DIEs (most, even?) are read twice. It would 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown be smarter to make parse_{var,type}_DIE return a Bool indicating 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown whether or not they advanced the DIE cursor, and only if they 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown didn't should read_DIE itself read through the DIE. 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(addVar) and add_var_to_arange: quite a lot of DiAddrRanges have 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown zero variables in their .vars XArray. Rather than have an XArray 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown with zero elements (which uses 2 malloc'd blocks), allow the .vars 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pointer to be NULL in this case. 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown More generally, reduce the amount of memory allocated and freed 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while reading Dwarf3 type/variable information. Even modest (20MB) 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown objects cause this module to allocate and free hundreds of 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown thousands of small blocks, and ML_(arena_malloc) and its various 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown groupies always show up at the top of performance profiles. */ 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_basics.h" 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_debuginfo.h" 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcbase.h" 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcassert.h" 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcprint.h" 143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_libcsetjmp.h" // setjmp facilities 144663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include "pub_core_hashtable.h" 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_options.h" 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_tooliface.h" /* VG_(needs) */ 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_xarray.h" 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_wordfm.h" 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "priv_misc.h" /* dinfo_zalloc/free */ 150436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "priv_image.h" 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "priv_tytypes.h" 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "priv_d3basics.h" 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "priv_storage.h" 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "priv_readdwarf3.h" /* self */ 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Basic machinery for parsing DIEs. ---*/ 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define TRACE_D3(format, args...) \ 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (td3) { VG_(printf)(format, ## args); } 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define D3_INVALID_CUOFF ((UWord)(-1UL)) 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define D3_FAKEVOID_CUOFF ((UWord)(-2UL)) 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 171436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice sli; // to which this cursor applies 172436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiOffT sli_next; // offset in underlying DiImage; must be >= sli.ioff 173436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov void (*barf)( const HChar* ) __attribute__((noreturn)); 174436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* barfstr; 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Cursor; 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline Bool is_sane_Cursor ( Cursor* c ) { 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!c) return False; 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!c->barf) return False; 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!c->barfstr) return False; 182436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (!ML_(sli_is_valid)(c->sli)) return False; 183436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (c->sli.ioff == DiOffT_INVALID) return False; 184436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (c->sli_next < c->sli.ioff) return False; 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 188436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov// Initialise a cursor from a DiSlice (ELF section, really) so as to 189436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov// start reading at offset |sli_initial_offset| from the start of the 190436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov// slice. 191436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void init_Cursor ( /*OUT*/Cursor* c, 192436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice sli, 193436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong sli_initial_offset, 194436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov __attribute__((noreturn)) void (*barf)(const HChar*), 195436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* barfstr ) 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(c); 198436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(bzero_inline)(c, sizeof(*c)); 199436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov c->sli = sli; 200436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov c->sli_next = c->sli.ioff + sli_initial_offset; 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->barf = barf; 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->barfstr = barfstr; 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(is_sane_Cursor(c)); 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool is_at_end_Cursor ( Cursor* c ) { 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(is_sane_Cursor(c)); 208436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return c->sli_next >= c->sli.ioff + c->sli.szB; 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 211436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic inline ULong get_position_of_Cursor ( Cursor* c ) { 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(is_sane_Cursor(c)); 213436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return c->sli_next - c->sli.ioff; 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 215436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic inline void set_position_of_Cursor ( Cursor* c, ULong pos ) { 216436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov c->sli_next = c->sli.ioff + pos; 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(is_sane_Cursor(c)); 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 220436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic /*signed*/Long get_remaining_length_Cursor ( Cursor* c ) { 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(is_sane_Cursor(c)); 222436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return c->sli.ioff + c->sli.szB - c->sli_next; 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 225436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//static void* get_address_of_Cursor ( Cursor* c ) { 226436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov// vg_assert(is_sane_Cursor(c)); 227436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov// return &c->region_start_img[ c->region_next ]; 228436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//} 229436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 230436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic DiCursor get_DiCursor_from_Cursor ( Cursor* c ) { 231436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return mk_DiCursor(c->sli.img, c->sli_next); 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* FIXME: document assumptions on endianness for 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown get_UShort/UInt/ULong. */ 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UChar get_UChar ( Cursor* c ) { 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar r; 238436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vg_assert(is_sane_Cursor(c)); 239436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (c->sli_next + sizeof(UChar) > c->sli.ioff + c->sli.szB) { 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->barf(c->barfstr); 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(0); 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 244436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r = ML_(img_get_UChar)(c->sli.img, c->sli_next); 245436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov c->sli_next += sizeof(UChar); 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return r; 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UShort get_UShort ( Cursor* c ) { 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UShort r; 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(is_sane_Cursor(c)); 251436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (c->sli_next + sizeof(UShort) > c->sli.ioff + c->sli.szB) { 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->barf(c->barfstr); 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(0); 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 256436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r = ML_(img_get_UShort)(c->sli.img, c->sli_next); 257436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov c->sli_next += sizeof(UShort); 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return r; 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt get_UInt ( Cursor* c ) { 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt r; 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(is_sane_Cursor(c)); 263436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (c->sli_next + sizeof(UInt) > c->sli.ioff + c->sli.szB) { 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->barf(c->barfstr); 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(0); 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 268436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r = ML_(img_get_UInt)(c->sli.img, c->sli_next); 269436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov c->sli_next += sizeof(UInt); 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return r; 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic ULong get_ULong ( Cursor* c ) { 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong r; 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(is_sane_Cursor(c)); 275436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (c->sli_next + sizeof(ULong) > c->sli.ioff + c->sli.szB) { 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->barf(c->barfstr); 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(0); 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 280436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov r = ML_(img_get_ULong)(c->sli.img, c->sli_next); 281436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov c->sli_next += sizeof(ULong); 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return r; 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 284436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic ULong get_ULEB128 ( Cursor* c ) { 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong result; 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int shift; 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar byte; 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* unroll first iteration */ 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown byte = get_UChar( c ); 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result = (ULong)(byte & 0x7f); 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (LIKELY(!(byte & 0x80))) return result; 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown shift = 7; 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* end unroll first iteration */ 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown byte = get_UChar( c ); 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result |= ((ULong)(byte & 0x7f)) << shift; 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown shift += 7; 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (byte & 0x80); 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return result; 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Long get_SLEB128 ( Cursor* c ) { 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong result = 0; 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int shift = 0; 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar byte; 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown byte = get_UChar(c); 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result |= ((ULong)(byte & 0x7f)) << shift; 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown shift += 7; 309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (byte & 0x80); 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (shift < 64 && (byte & 0x40)) 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown result |= -(1ULL << shift); 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return result; 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 315436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Assume 'c' points to the start of a string. Return a DiCursor of 316436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov whatever it points at, and advance it past the terminating zero. 317436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov This makes it safe for the caller to then copy the string with 318436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ML_(addStr), since (w.r.t. image overruns) the process of advancing 319436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov past the terminating zero will already have "vetted" the string. */ 320436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic DiCursor get_AsciiZ ( Cursor* c ) { 321436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UChar uc; 322436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiCursor res = get_DiCursor_from_Cursor(c); 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { uc = get_UChar(c); } while (uc != 0); 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return res; 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic ULong peek_ULEB128 ( Cursor* c ) { 328436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiOffT here = c->sli_next; 329436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong r = get_ULEB128( c ); 330436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov c->sli_next = here; 331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return r; 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UChar peek_UChar ( Cursor* c ) { 334436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiOffT here = c->sli_next; 335436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UChar r = get_UChar( c ); 336436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov c->sli_next = here; 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return r; 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic ULong get_Dwarfish_UWord ( Cursor* c, Bool is_dw64 ) { 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return is_dw64 ? get_ULong(c) : (ULong) get_UInt(c); 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UWord get_UWord ( Cursor* c ) { 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(sizeof(UWord) == sizeof(void*)); 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (sizeof(UWord) == 4) return get_UInt(c); 347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (sizeof(UWord) == 8) return get_ULong(c); 348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(0); 349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Read a DWARF3 'Initial Length' field */ 352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic ULong get_Initial_Length ( /*OUT*/Bool* is64, 353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Cursor* c, 354436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const HChar* barfMsg ) 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong w64; 357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt w32; 358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *is64 = False; 359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown w32 = get_UInt( c ); 360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (w32 >= 0xFFFFFFF0 && w32 < 0xFFFFFFFF) { 361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->barf( barfMsg ); 362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (w32 == 0xFFFFFFFF) { 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *is64 = True; 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown w64 = get_ULong( c ); 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *is64 = False; 368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown w64 = (ULong)w32; 369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return w64; 371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- "CUConst" structure ---*/ 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define N_ABBV_CACHE 32 381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Holds information that is constant through the parsing of a 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Compilation Unit. This is basically plumbed through to 384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown everywhere. */ 385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Call here if anything goes wrong */ 388436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov void (*barf)( const HChar* ) __attribute__((noreturn)); 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Is this 64-bit DWARF ? */ 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool is_dw64; 391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Which DWARF version ? (2, 3 or 4) */ 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UShort version; 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Length of this Compilation Unit, as stated in the 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .unit_length :: InitialLength field of the CU Header. 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown However, this size (as specified by the D3 spec) does not 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown include the size of the .unit_length field itself, which is 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown either 4 or 12 bytes (32-bit or 64-bit Dwarf3). That value 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown can be obtained through the expression ".is_dw64 ? 12 : 4". */ 399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong unit_length; 400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Offset of start of this unit in .debug_info */ 401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord cu_start_offset; 402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* SVMA for this CU. In the D3 spec, is known as the "base 403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown address of the compilation unit (last para sec 3.1.1). 404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Needed for (amongst things) interpretation of location-list 405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown values. */ 406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr cu_svma; 407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool cu_svma_known; 408436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* The debug_abbreviations table to be used for this Unit */ 410436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov //UChar* debug_abbv; 411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Upper bound on size thereof (an overestimate, in general) */ 412436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov //UWord debug_abbv_maxszB; 413436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* A bounded area of the image, to be used as the 414436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov debug_abbreviations table tobe used for this Unit. */ 415436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice debug_abbv; 416436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 417436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Image information for various sections. */ 418436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_str; 419436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_ranges; 420436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_loc; 421436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_line; 422436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_info; 423436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_types; 424436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_info_alt; 425436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_str_alt; 426663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* How much to add to .debug_types resp. alternate .debug_info offsets 427663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng in cook_die*. */ 428663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UWord types_cuOff_bias; 429663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UWord alt_cuOff_bias; 430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- Needed so we can add stuff to the string table. --- */ 431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct _DebugInfo* di; 432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- a cache for set_abbv_Cursor --- */ 433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* abbv_code == (ULong)-1 for an unused entry. */ 434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { ULong abbv_code; UWord posn; } saC_cache[N_ABBV_CACHE]; 435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord saC_cache_queries; 436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord saC_cache_misses; 437663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 438663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* True if this came from .debug_types; otherwise it came from 439663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng .debug_info. */ 440663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool is_type_unit; 441663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* For a unit coming from .debug_types, these hold the TU's type 442663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng signature and the uncooked DIE offset of the TU's signatured 443663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng type. For a unit coming from .debug_info, these are unused. */ 444663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong type_signature; 445663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong type_offset; 446663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 447663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Signatured type hash; computed once and then shared by all 448663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng CUs. */ 449663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VgHashTable signature_types; 450663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 451663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* True if this came from alternate .debug_info; otherwise 452663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng it came from normal .debug_info or .debug_types. */ 453663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool is_alt_info; 454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CUConst; 456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 458663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Return the cooked value of DIE depending on whether CC represents a 459663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng .debug_types unit. To cook a DIE, we pretend that the .debug_info, 460663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng .debug_types and optional alternate .debug_info sections form 461663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng a contiguous whole, so that DIEs coming from .debug_types are numbered 462663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng starting at the end of .debug_info and DIEs coming from alternate 463663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng .debug_info are numbered starting at the end of .debug_types. */ 464663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic UWord cook_die( CUConst* cc, UWord die ) 465663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 466663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (cc->is_type_unit) 467663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng die += cc->types_cuOff_bias; 468663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else if (cc->is_alt_info) 469663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng die += cc->alt_cuOff_bias; 470663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return die; 471663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 472663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 473663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Like cook_die, but understand that DIEs coming from a 474663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DW_FORM_ref_sig8 reference are already cooked. Also, handle 475663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DW_FORM_GNU_ref_alt from within primary .debug_info or .debug_types 476663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng as reference to alternate .debug_info. */ 477663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic UWord cook_die_using_form( CUConst *cc, UWord die, DW_FORM form) 478663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 479663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (form == DW_FORM_ref_sig8) 480663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return die; 481663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (form == DW_FORM_GNU_ref_alt) 482663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return die + cc->alt_cuOff_bias; 483663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return cook_die( cc, die ); 484663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 485663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 486663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Return the uncooked offset of DIE and set *TYPE_FLAG to true if the DIE 487663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng came from the .debug_types section and *ALT_FLAG to true if the DIE 488663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng came from alternate .debug_info section. */ 489663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic UWord uncook_die( CUConst *cc, UWord die, /*OUT*/Bool *type_flag, 490663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool *alt_flag ) 491663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 492663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *alt_flag = False; 493663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *type_flag = False; 494436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* The use of escn_debug_{info,types}.szB seems safe to me even if 495436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov escn_debug_{info,types} are DiSlice_INVALID (meaning the 496436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sections were not found), because DiSlice_INVALID.szB is always 497436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov zero. That said, it seems unlikely we'd ever get here if 498436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov .debug_info or .debug_types were missing. */ 499436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (die >= cc->escn_debug_info.szB) { 500436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (die >= cc->escn_debug_info.szB + cc->escn_debug_types.szB) { 501663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *alt_flag = True; 502436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov die -= cc->escn_debug_info.szB + cc->escn_debug_types.szB; 503663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 504663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng *type_flag = True; 505436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov die -= cc->escn_debug_info.szB; 506663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 507663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 508663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return die; 509663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 510663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Helper functions for Guarded Expressions ---*/ 514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Parse the location list starting at img-offset 'debug_loc_offset' 518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in .debug_loc. Results are biased with 'svma_of_referencing_CU' 519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and so I believe are correct SVMAs for the object as a whole. This 520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown function allocates the UChar*, and the caller must deallocate it. 521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The resulting block is in so-called Guarded-Expression format. 522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Guarded-Expression format is similar but not identical to the DWARF3 524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown location-list format. The format of each returned block is: 525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar biasMe; 527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar isEnd; 528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown followed by zero or more of 529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (Addr aMin; Addr aMax; UShort nbytes; ..bytes..; UChar isEnd) 531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown '..bytes..' is an standard DWARF3 location expression which is 533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown valid when aMin <= pc <= aMax (possibly after suitable biasing). 534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The number of bytes in '..bytes..' is nbytes. 536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The end of the sequence is marked by an isEnd == 1 value. All 538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown previous isEnd values must be zero. 539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown biasMe is 1 if the aMin/aMax fields need this DebugInfo's 541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown text_bias added before use, and 0 if the GX is this is not 542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown necessary (is ready to go). 543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Hence the block can be quickly parsed and is self-describing. Note 545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that aMax is 1 less than the corresponding value in a DWARF3 546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown location list. Zero length ranges, with aMax == aMin-1, are not 547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown allowed. 548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 2008-sept-12: moved ML_(pp_GX) from here to d3basics.c, where 550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown it more logically belongs. */ 551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Apply a text bias to a GX. */ 554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void bias_GX ( /*MOD*/GExpr* gx, struct _DebugInfo* di ) 555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UShort nbytes; 557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar* p = &gx->payload[0]; 558b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov UChar* pA; 559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar uc; 560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown uc = *p++; /*biasMe*/ 561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (uc == 0) 562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(uc == 1); 564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p[-1] = 0; /* mark it as done */ 565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown uc = *p++; 567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (uc == 1) 568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; /*isEnd*/ 569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(uc == 0); 570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* t-bias aMin */ 571b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pA = (UChar*)p; 572b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ML_(write_Addr)(pA, ML_(read_Addr)(pA) + di->text_debug_bias); 573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p += sizeof(Addr); 574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* t-bias aMax */ 575b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov pA = (UChar*)p; 576b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ML_(write_Addr)(pA, ML_(read_Addr)(pA) + di->text_debug_bias); 577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p += sizeof(Addr); 578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* nbytes, and actual expression */ 579b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov nbytes = ML_(read_UShort)(p); p += sizeof(UShort); 580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p += nbytes; 581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline)) 585436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic GExpr* make_singleton_GX ( DiCursor block, ULong nbytes ) 586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SizeT bytesReqd; 588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GExpr* gx; 589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar *p, *pstart; 590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(sizeof(UWord) == sizeof(Addr)); 592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(nbytes <= 0xFFFF); /* else we overflow the nbytes field */ 593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bytesReqd 594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = sizeof(UChar) /*biasMe*/ + sizeof(UChar) /*!isEnd*/ 595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown + sizeof(UWord) /*aMin*/ + sizeof(UWord) /*aMax*/ 596436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov + sizeof(UShort) /*nbytes*/ + (SizeT)nbytes 597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown + sizeof(UChar); /*isEnd*/ 598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gx = ML_(dinfo_zalloc)( "di.readdwarf3.msGX.1", 600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(GExpr) + bytesReqd ); 601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(gx); 602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown p = pstart = &gx->payload[0]; 604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 605b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p = ML_(write_UChar)(p, 0); /*biasMe*/ 606b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p = ML_(write_UChar)(p, 0); /*!isEnd*/ 607b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p = ML_(write_Addr)(p, 0); /*aMin*/ 608b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p = ML_(write_Addr)(p, ~0); /*aMax*/ 609b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p = ML_(write_UShort)(p, nbytes); /*nbytes*/ 610436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ML_(cur_read_get)(p, block, nbytes); p += nbytes; 611b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov p = ML_(write_UChar)(p, 1); /*isEnd*/ 612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert( (SizeT)(p - pstart) == bytesReqd); 614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert( &gx->payload[bytesReqd] 615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown == ((UChar*)gx) + sizeof(GExpr) + bytesReqd ); 616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return gx; 618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline)) 621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic GExpr* make_general_GX ( CUConst* cc, 622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool td3, 623436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong debug_loc_offset, 624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr svma_of_referencing_CU ) 625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr base; 627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Cursor loc; 628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* xa; /* XArray of UChar */ 629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GExpr* gx; 630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word nbytes; 631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(sizeof(UWord) == sizeof(Addr)); 633436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (!ML_(sli_is_valid)(cc->escn_debug_loc) || cc->escn_debug_loc.szB == 0) 634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf("make_general_GX: .debug_loc is empty/missing"); 635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 636436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov init_Cursor( &loc, cc->escn_debug_loc, 0, cc->barf, 637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "Overrun whilst reading .debug_loc section(2)" ); 638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set_position_of_Cursor( &loc, debug_loc_offset ); 639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 640436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3("make_general_GX (.debug_loc_offset = %llu, ioff = %llu) {\n", 641436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov debug_loc_offset, (ULong)get_DiCursor_from_Cursor(&loc).ioff ); 642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Who frees this xa? It is freed before this fn exits. */ 644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.mgGX.1", 645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(dinfo_free), 646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(UChar) ); 647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { UChar c = 1; /*biasMe*/ VG_(addBytesToXA)( xa, &c, sizeof(c) ); } 649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown base = 0; 651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool acquire; 653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord len; 654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Read a (host-)word pair. This is something of a hack since 655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the word size to read is really dictated by the ELF file; 656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown however, we assume we're reading a file with the same 657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown word-sizeness as the host. Reasonably enough. */ 658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord w1 = get_UWord( &loc ); 659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord w2 = get_UWord( &loc ); 660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" %08lx %08lx\n", w1, w2); 662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (w1 == 0 && w2 == 0) 663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; /* end of list */ 664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (w1 == -1UL) { 666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* new value for 'base' */ 667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown base = w2; 668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* else a location expression follows */ 672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* else enumerate [w1+base, w2+base) */ 673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* w2 is 1 past end of range, as per D3 defn for "DW_AT_high_pc" 674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (sec 2.17.2) */ 675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (w1 > w2) { 676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("negative range is for .debug_loc expr at " 677436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "file offset %llu\n", 678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown debug_loc_offset); 679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf( "negative range in .debug_loc section" ); 680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* ignore zero length ranges */ 683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown acquire = w1 < w2; 684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len = (UWord)get_UShort( &loc ); 685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (acquire) { 687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord w; 688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UShort s; 689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar c; 690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c = 0; /* !isEnd*/ 691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addBytesToXA)( xa, &c, sizeof(c) ); 692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown w = w1 + base + svma_of_referencing_CU; 693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addBytesToXA)( xa, &w, sizeof(w) ); 694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown w = w2 -1 + base + svma_of_referencing_CU; 695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addBytesToXA)( xa, &w, sizeof(w) ); 696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s = (UShort)len; 697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addBytesToXA)( xa, &s, sizeof(s) ); 698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (len > 0) { 701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar byte = get_UChar( &loc ); 702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("%02x", (UInt)byte); 703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (acquire) 704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addBytesToXA)( xa, &byte, 1 ); 705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len--; 706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("\n"); 708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { UChar c = 1; /*isEnd*/ VG_(addBytesToXA)( xa, &c, sizeof(c) ); } 711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown nbytes = VG_(sizeXA)( xa ); 713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(nbytes >= 1); 714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gx = ML_(dinfo_zalloc)( "di.readdwarf3.mgGX.2", sizeof(GExpr) + nbytes ); 716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(gx); 717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memcpy)( &gx->payload[0], (UChar*)VG_(indexXA)(xa,0), nbytes ); 718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert( &gx->payload[nbytes] 719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown == ((UChar*)gx) + sizeof(GExpr) + nbytes ); 720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(deleteXA)( xa ); 722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("}\n"); 724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return gx; 726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Helper functions for range lists and CU headers ---*/ 732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Denotes an address range. Both aMin and aMax are included in the 736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown range; hence a complete range is (0, ~0) and an empty range is any 737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (X, X-1) for X > 0.*/ 738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { Addr aMin; Addr aMax; } 740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddrRange; 741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Generate an arbitrary structural total ordering on 744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* of AddrRange. */ 745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Word cmp__XArrays_of_AddrRange ( XArray* rngs1, XArray* rngs2 ) 746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word n1, n2, i; 748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(rngs1 && rngs2); 749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n1 = VG_(sizeXA)( rngs1 ); 750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n2 = VG_(sizeXA)( rngs2 ); 751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (n1 < n2) return -1; 752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (n1 > n2) return 1; 753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n1; i++) { 754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddrRange* rng1 = (AddrRange*)VG_(indexXA)( rngs1, i ); 755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddrRange* rng2 = (AddrRange*)VG_(indexXA)( rngs2, i ); 756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (rng1->aMin < rng2->aMin) return -1; 757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (rng1->aMin > rng2->aMin) return 1; 758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (rng1->aMax < rng2->aMax) return -1; 759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (rng1->aMax > rng2->aMax) return 1; 760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline)) 766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic XArray* /* of AddrRange */ empty_range_list ( void ) 767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* xa; /* XArray of AddrRange */ 769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Who frees this xa? varstack_preen() does. */ 770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.erl.1", 771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(dinfo_free), 772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(AddrRange) ); 773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return xa; 774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline)) 778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic XArray* unitary_range_list ( Addr aMin, Addr aMax ) 779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* xa; 781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddrRange pair; 782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(aMin <= aMax); 783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Who frees this xa? varstack_preen() does. */ 784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.url.1", 785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(dinfo_free), 786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(AddrRange) ); 787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pair.aMin = aMin; 788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pair.aMax = aMax; 789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToXA)( xa, &pair ); 790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return xa; 791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Enumerate the address ranges starting at img-offset 795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'debug_ranges_offset' in .debug_ranges. Results are biased with 796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'svma_of_referencing_CU' and so I believe are correct SVMAs for the 797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown object as a whole. This function allocates the XArray, and the 798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown caller must deallocate it. */ 799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline)) 800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic XArray* /* of AddrRange */ 801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown get_range_list ( CUConst* cc, 802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool td3, 803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord debug_ranges_offset, 804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr svma_of_referencing_CU ) 805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr base; 807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Cursor ranges; 808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* xa; /* XArray of AddrRange */ 809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddrRange pair; 810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 811436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (!ML_(sli_is_valid)(cc->escn_debug_ranges) 812436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov || cc->escn_debug_ranges.szB == 0) 813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf("get_range_list: .debug_ranges is empty/missing"); 814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 815436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov init_Cursor( &ranges, cc->escn_debug_ranges, 0, cc->barf, 816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "Overrun whilst reading .debug_ranges section(2)" ); 817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set_position_of_Cursor( &ranges, debug_ranges_offset ); 818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Who frees this xa? varstack_preen() does. */ 820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown xa = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.grl.1", ML_(dinfo_free), 821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(AddrRange) ); 822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown base = 0; 823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Read a (host-)word pair. This is something of a hack since 825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the word size to read is really dictated by the ELF file; 826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown however, we assume we're reading a file with the same 827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown word-sizeness as the host. Reasonably enough. */ 828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord w1 = get_UWord( &ranges ); 829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord w2 = get_UWord( &ranges ); 830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (w1 == 0 && w2 == 0) 832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; /* end of list. */ 833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (w1 == -1UL) { 835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* new value for 'base' */ 836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown base = w2; 837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* else enumerate [w1+base, w2+base) */ 841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* w2 is 1 past end of range, as per D3 defn for "DW_AT_high_pc" 842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (sec 2.17.2) */ 843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (w1 > w2) 844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf( "negative range in .debug_ranges section" ); 845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (w1 < w2) { 846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pair.aMin = w1 + base + svma_of_referencing_CU; 847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pair.aMax = w2 - 1 + base + svma_of_referencing_CU; 848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(pair.aMin <= pair.aMax); 849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToXA)( xa, &pair ); 850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return xa; 853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Parse the Compilation Unit header indicated at 'c' and 857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown initialise 'cc' accordingly. */ 858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic __attribute__((noinline)) 859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid parse_CU_Header ( /*OUT*/CUConst* cc, 860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool td3, 861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Cursor* c, 862436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_abbv, 863663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool type_unit, 864663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool alt_info ) 865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar address_size; 867436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong debug_abbrev_offset; 868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(cc, 0, sizeof(*cc)); 871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(c && c->barf); 872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf = c->barf; 873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* initial_length field */ 875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->unit_length 876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = get_Initial_Length( &cc->is_dw64, c, 877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "parse_CU_Header: invalid initial-length field" ); 878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" Length: %lld\n", cc->unit_length ); 880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* version */ 882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->version = get_UShort( c ); 883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (cc->version != 2 && cc->version != 3 && cc->version != 4) 884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf( "parse_CU_Header: is neither DWARF2 nor DWARF3 nor DWARF4" ); 885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" Version: %d\n", (Int)cc->version ); 886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* debug_abbrev_offset */ 888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown debug_abbrev_offset = get_Dwarfish_UWord( c, cc->is_dw64 ); 889436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (debug_abbrev_offset >= escn_debug_abbv.szB) 890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf( "parse_CU_Header: invalid debug_abbrev_offset" ); 891436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3(" Abbrev Offset: %lld\n", debug_abbrev_offset ); 892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* address size. If this isn't equal to the host word size, just 894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown give up. This makes it safe to assume elsewhere that 895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_FORM_addr and DW_FORM_ref_addr can be treated as a host 896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown word. */ 897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown address_size = get_UChar( c ); 898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (address_size != sizeof(void*)) 899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf( "parse_CU_Header: invalid address_size" ); 900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" Pointer Size: %d\n", (Int)address_size ); 901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 902663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc->is_type_unit = type_unit; 903663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc->is_alt_info = alt_info; 904663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 905663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (type_unit) { 906663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc->type_signature = get_ULong( c ); 907663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc->type_offset = get_Dwarfish_UWord( c, cc->is_dw64 ); 908663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 909663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 910436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Set up cc->debug_abbv to point to the relevant table for this 911436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov CU. Set its .szB so that at least we can't read off the end of 912436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov the debug_abbrev section -- potentially (and quite likely) too 913436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov big, if this isn't the last table in the section, but at least 914436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov it's safe. 915436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 916436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov This amounts to taking debug_abbv_escn and moving the start 917436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov position along by debug_abbrev_offset bytes, hence forming a 918436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov smaller DiSlice which has the same end point. Since we checked 919436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov just above that debug_abbrev_offset is less than the size of 920436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov debug_abbv_escn, this should leave us with a nonempty slice. */ 921436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vg_assert(debug_abbrev_offset < escn_debug_abbv.szB); 922436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc->debug_abbv = escn_debug_abbv; 923436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc->debug_abbv.ioff += debug_abbrev_offset; 924436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc->debug_abbv.szB -= debug_abbrev_offset; 925436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* and empty out the set_abbv_Cursor cache */ 927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) VG_(printf)("XXXXXX initialise set_abbv_Cursor cache\n"); 928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < N_ABBV_CACHE; i++) { 929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->saC_cache[i].abbv_code = (ULong)-1; /* unused */ 930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->saC_cache[i].posn = 0; 931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->saC_cache_queries = 0; 933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->saC_cache_misses = 0; 934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 936ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 937ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Set up 'c' so it is ready to parse the abbv table entry code 938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'abbv_code' for this compilation unit. */ 939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic __attribute__((noinline)) 940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid set_abbv_Cursor ( /*OUT*/Cursor* c, Bool td3, 941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CUConst* cc, ULong abbv_code ) 942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int i; 944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong acode; 945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (abbv_code == 0) 947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf("set_abbv_Cursor: abbv_code == 0" ); 948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* (ULong)-1 is used to represent an empty cache slot. So we can't 950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown allow it. In any case no valid DWARF3 should make a reference 951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to a negative abbreviation code. [at least, they always seem to 952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown be numbered upwards from zero as far as I have seen] */ 953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(abbv_code != (ULong)-1); 954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* First search the cache. */ 956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) VG_(printf)("XXXXXX search set_abbv_Cursor cache\n"); 957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->saC_cache_queries++; 958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < N_ABBV_CACHE; i++) { 959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* No need to test the cached abbv_codes for -1 (empty), since 960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown we just asserted that abbv_code is not -1. */ 961436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (LIKELY(cc->saC_cache[i].abbv_code == abbv_code)) { 962436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Found it. Set up the parser using the cached position, 963436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov and move this cache entry to the front. */ 964436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (0) VG_(printf)("XXXXXX found in set_abbv_Cursor cache\n"); 965436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov init_Cursor( c, cc->debug_abbv, cc->saC_cache[i].posn, 966436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc->barf, 967436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "Overrun whilst parsing .debug_abbrev section(1)" ); 968436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (i > 0) { 969436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong t_abbv_code = cc->saC_cache[i].abbv_code; 970436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UWord t_posn = cc->saC_cache[i].posn; 971436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov while (i > 0) { 972436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc->saC_cache[i] = cc->saC_cache[i-1]; 973436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov i--; 974436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 975436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc->saC_cache[0].abbv_code = t_abbv_code; 976436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc->saC_cache[0].posn = t_posn; 977436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 978436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; 979436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* No. It's not in the cache. We have to search through 983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .debug_abbrev, of course taking care to update the cache 984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown when done. */ 985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->saC_cache_misses++; 987436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov init_Cursor( c, cc->debug_abbv, 0, cc->barf, 988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "Overrun whilst parsing .debug_abbrev section(2)" ); 989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Now iterate though the table until we find the requested 991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown entry. */ 992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //ULong atag; 994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //UInt has_children; 995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown acode = get_ULEB128( c ); 996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (acode == 0) break; /* end of the table */ 997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (acode == abbv_code) break; /* found it */ 998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*atag = */ get_ULEB128( c ); 999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*has_children = */ get_UChar( c ); 1000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //TRACE_D3(" %llu %s [%s]\n", 1001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // acode, pp_DW_TAG(atag), pp_DW_children(has_children)); 1002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 1003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong at_name = get_ULEB128( c ); 1004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong at_form = get_ULEB128( c ); 1005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (at_name == 0 && at_form == 0) break; 1006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //TRACE_D3(" %18s %s\n", 1007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // pp_DW_AT(at_name), pp_DW_FORM(at_form)); 1008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (acode == 0) { 1012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Not found. This is fatal. */ 1013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf("set_abbv_Cursor: abbv_code not found"); 1014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Otherwise, 'c' is now set correctly to parse the relevant entry, 1017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown starting from the abbreviation entry's tag. So just cache 1018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the result, and return. */ 1019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = N_ABBV_CACHE-1; i > N_ABBV_CACHE/2; i--) { 1020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->saC_cache[i] = cc->saC_cache[i-1]; 1021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) VG_(printf)("XXXXXX update set_abbv_Cursor cache\n"); 1023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->saC_cache[N_ABBV_CACHE/2].abbv_code = abbv_code; 1024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->saC_cache[N_ABBV_CACHE/2].posn = get_position_of_Cursor(c); 1025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1027663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* This represents a single signatured type. It maps a type signature 1028663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (a ULong) to a cooked DIE offset. Objects of this type are stored 1029663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng in the type signature hash table. */ 1030663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef 1031663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng struct D3SignatureType { 1032663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng struct D3SignatureType *next; 1033663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UWord data; 1034663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong type_signature; 1035663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UWord die; 1036663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1037663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng D3SignatureType; 1038663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1039663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Record a signatured type in the hash table. */ 1040663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic void record_signatured_type ( VgHashTable tab, 1041663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong type_signature, 1042663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UWord die ) 1043663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 1044663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng D3SignatureType *dstype = ML_(dinfo_zalloc) ( "di.readdwarf3.sigtype", 1045663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng sizeof(D3SignatureType) ); 1046663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dstype->data = (UWord) type_signature; 1047663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dstype->type_signature = type_signature; 1048663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dstype->die = die; 1049663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(HT_add_node) ( tab, dstype ); 1050663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 1051663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1052663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Given a type signature hash table and a type signature, return the 1053663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cooked DIE offset of the type. If the type cannot be found, call 1054663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng BARF. */ 1055663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstatic UWord lookup_signatured_type ( VgHashTable tab, 1056663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong type_signature, 1057436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov void (*barf)( const HChar* ) __attribute__((noreturn)) ) 1058663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 1059663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng D3SignatureType *dstype = VG_(HT_lookup) ( tab, (UWord) type_signature ); 1060663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* This may be unwarranted chumminess with the hash table 1061663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng implementation. */ 1062663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng while ( dstype != NULL && dstype->type_signature != type_signature) 1063663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng dstype = dstype->next; 1064663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (dstype == NULL) { 1065663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng barf("lookup_signatured_type: could not find signatured type"); 1066663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /*NOTREACHED*/ 1067663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vg_assert(0); 1068663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1069663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return dstype->die; 1070663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 1071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1073436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Represents Form data. If szB is 1/2/4/8 then the result is in the 1074436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov lowest 1/2/4/8 bytes of u.val. If szB is zero or negative then the 1075436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov result is an image section beginning at u.cur and with size -szB. 1076436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov No other szB values are allowed. */ 1077436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef 1078436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov struct { 1079436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Long szB; // 1, 2, 4, 8 or non-positive values only. 1080436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov union { ULong val; DiCursor cur; } u; 1081436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1082436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov FormContents; 1083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1084436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* From 'c', get the Form data into 'cts'. Either it gets a 1/2/4/8 1085436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov byte scalar value, or (a reference to) zero or more bytes starting 1086436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov at a DiCursor.*/ 1087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 1088436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid get_Form_contents ( /*OUT*/FormContents* cts, 1089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CUConst* cc, Cursor* c, 1090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool td3, DW_FORM form ) 1091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1092436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(bzero_inline)(cts, sizeof(*cts)); 1093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (form) { 1094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_data1: 1095436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.val = (ULong)(UChar)get_UChar(c); 1096436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = 1; 1097436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3("%u", (UInt)cts->u.val); 1098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_data2: 1100436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.val = (ULong)(UShort)get_UShort(c); 1101436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = 2; 1102436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3("%u", (UInt)cts->u.val); 1103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_data4: 1105436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.val = (ULong)(UInt)get_UInt(c); 1106436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = 4; 1107436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3("%u", (UInt)cts->u.val); 1108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_data8: 1110436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.val = get_ULong(c); 1111436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = 8; 1112436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3("%llu", cts->u.val); 1113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_sec_offset: 1115436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.val = (ULong)get_Dwarfish_UWord( c, cc->is_dw64 ); 1116436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = cc->is_dw64 ? 8 : 4; 1117436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3("%llu", cts->u.val); 1118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_sdata: 1120436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.val = (ULong)(Long)get_SLEB128(c); 1121436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = 8; 1122436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3("%lld", (Long)cts->u.val); 1123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_udata: 1125436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.val = (ULong)(Long)get_ULEB128(c); 1126436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = 8; 1127436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3("%llu", (Long)cts->u.val); 1128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_addr: 1130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* note, this is a hack. DW_FORM_addr is defined as getting 1131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a word the size of the target machine as defined by the 1132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown address_size field in the CU Header. However, 1133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parse_CU_Header() rejects all inputs except those for 1134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which address_size == sizeof(Word), hence we can just 1135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown treat it as a (host) Word. */ 1136436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.val = (ULong)(UWord)get_UWord(c); 1137436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = sizeof(UWord); 1138436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3("0x%lx", (UWord)cts->u.val); 1139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_ref_addr: 1142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* We make the same word-size assumption as DW_FORM_addr. */ 1143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* What does this really mean? From D3 Sec 7.5.4, 1144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown description of "reference", it would appear to reference 1145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown some other DIE, by specifying the offset from the 1146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown beginning of a .debug_info section. The D3 spec mentions 1147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that this might be in some other shared object and 1148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown executable. But I don't see how the name of the other 1149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown object/exe is specified. 1150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown At least for the DW_FORM_ref_addrs created by icc11, the 1152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown references seem to be within the same object/executable. 1153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown So for the moment we merely range-check, to see that they 1154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown actually do specify a plausible offset within this 1155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown object's .debug_info, and return the value unchanged. 1156663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1157663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng In DWARF 2, DW_FORM_ref_addr is address-sized, but in 1158663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DWARF 3 and later, it is offset-sized. 1159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1160663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (cc->version == 2) { 1161436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.val = (ULong)(UWord)get_UWord(c); 1162436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = sizeof(UWord); 1163663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 1164436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.val = get_Dwarfish_UWord(c, cc->is_dw64); 1165436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = cc->is_dw64 ? sizeof(ULong) : sizeof(UInt); 1166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1167436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3("0x%lx", (UWord)cts->u.val); 1168436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (0) VG_(printf)("DW_FORM_ref_addr 0x%lx\n", (UWord)cts->u.val); 1169436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (/* the following is surely impossible, but ... */ 1170436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov !ML_(sli_is_valid)(cc->escn_debug_info) 1171436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov || cts->u.val >= (ULong)cc->escn_debug_info.szB) { 1172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Hmm. Offset is nonsensical for this object's .debug_info 1173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown section. Be safe and reject it. */ 1174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf("get_Form_contents: DW_FORM_ref_addr points " 1175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "outside .debug_info"); 1176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_strp: { 1180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* this is an offset into .debug_str */ 1181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord uw = (UWord)get_Dwarfish_UWord( c, cc->is_dw64 ); 1182436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (!ML_(sli_is_valid)(cc->escn_debug_str) 1183436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov || uw >= cc->escn_debug_str.szB) 1184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf("get_Form_contents: DW_FORM_strp " 1185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "points outside .debug_str"); 1186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* FIXME: check the entire string lies inside debug_str, 1187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown not just the first byte of it. */ 1188436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiCursor str 1189436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = ML_(cur_plus)( ML_(cur_from_sli)(cc->escn_debug_str), uw ); 1190436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (td3) { 1191436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HChar* tmp = ML_(cur_read_strdup)(str, "di.getFC.1"); 1192436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3("(indirect string, offset: 0x%lx): %s", uw, tmp); 1193436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ML_(dinfo_free)(tmp); 1194436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1195436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.cur = str; 1196436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = - (Long)(1 + (ULong)ML_(cur_strlen)(str)); 1197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_string: { 1200436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiCursor str = get_AsciiZ(c); 1201436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (td3) { 1202436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HChar* tmp = ML_(cur_read_strdup)(str, "di.getFC.2"); 1203436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3("%s", tmp); 1204436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ML_(dinfo_free)(tmp); 1205436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1206436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.cur = str; 1207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* strlen is safe because get_AsciiZ already 'vetted' the 1208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown entire string */ 1209436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = - (Long)(1 + (ULong)ML_(cur_strlen)(str)); 1210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_ref1: { 1213436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UChar u8 = get_UChar(c); 1214436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UWord res = cc->cu_start_offset + (UWord)u8; 1215436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.val = (ULong)res; 1216436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = sizeof(UWord); 1217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("<%lx>", res); 1218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_ref2: { 1221436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UShort u16 = get_UShort(c); 1222436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UWord res = cc->cu_start_offset + (UWord)u16; 1223436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.val = (ULong)res; 1224436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = sizeof(UWord); 1225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("<%lx>", res); 1226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_ref4: { 1229436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt u32 = get_UInt(c); 1230436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UWord res = cc->cu_start_offset + (UWord)u32; 1231436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.val = (ULong)res; 1232436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = sizeof(UWord); 1233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("<%lx>", res); 1234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_ref8: { 1237436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong u64 = get_ULong(c); 1238436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UWord res = cc->cu_start_offset + (UWord)u64; 1239436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.val = (ULong)res; 1240436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = sizeof(UWord); 1241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("<%lx>", res); 1242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_ref_udata: { 1245436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong u64 = get_ULEB128(c); 1246436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UWord res = cc->cu_start_offset + (UWord)u64; 1247436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.val = (ULong)res; 1248436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = sizeof(UWord); 1249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("<%lx>", res); 1250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_flag: { 1253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar u8 = get_UChar(c); 1254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("%u", (UInt)u8); 1255436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.val = (ULong)u8; 1256436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = 1; 1257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_flag_present: 1260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("1"); 1261436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.val = 1; 1262436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = 1; 1263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_block1: { 1265436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong u64b; 1266436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong u64 = (ULong)get_UChar(c); 1267436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiCursor block = get_DiCursor_from_Cursor(c); 1268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("%llu byte block: ", u64); 1269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (u64b = u64; u64b > 0; u64b--) { 1270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar u8 = get_UChar(c); 1271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("%x ", (UInt)u8); 1272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1273436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.cur = block; 1274436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = - (Long)u64; 1275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_block2: { 1278436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong u64b; 1279436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong u64 = (ULong)get_UShort(c); 1280436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiCursor block = get_DiCursor_from_Cursor(c); 1281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("%llu byte block: ", u64); 1282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (u64b = u64; u64b > 0; u64b--) { 1283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar u8 = get_UChar(c); 1284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("%x ", (UInt)u8); 1285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1286436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.cur = block; 1287436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = - (Long)u64; 1288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_block4: { 1291436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong u64b; 1292436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong u64 = (ULong)get_UInt(c); 1293436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiCursor block = get_DiCursor_from_Cursor(c); 1294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("%llu byte block: ", u64); 1295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (u64b = u64; u64b > 0; u64b--) { 1296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar u8 = get_UChar(c); 1297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("%x ", (UInt)u8); 1298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1299436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.cur = block; 1300436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = - (Long)u64; 1301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_exprloc: 1304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_block: { 1305436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong u64b; 1306436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong u64 = (ULong)get_ULEB128(c); 1307436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiCursor block = get_DiCursor_from_Cursor(c); 1308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("%llu byte block: ", u64); 1309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (u64b = u64; u64b > 0; u64b--) { 1310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar u8 = get_UChar(c); 1311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("%x ", (UInt)u8); 1312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1313436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.cur = block; 1314436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = - (Long)u64; 1315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_ref_sig8: { 1318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong u64b; 1319663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong signature = get_ULong (c); 1320663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ULong work = signature; 1321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("8 byte signature: "); 1322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (u64b = 8; u64b > 0; u64b--) { 1323663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UChar u8 = work & 0xff; 1324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("%x ", (UInt)u8); 1325663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng work >>= 8; 1326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1327663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Due to the way that the hash table is constructed, the 1328663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng resulting DIE offset here is already "cooked". See 1329663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cook_die_using_form. */ 1330436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.val = lookup_signatured_type (cc->signature_types, signature, 1331436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov c->barf); 1332436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = sizeof(UWord); 1333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_FORM_indirect: 1336436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov get_Form_contents (cts, cc, c, td3, (DW_FORM)get_ULEB128(c)); 1337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 1338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1339663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case DW_FORM_GNU_ref_alt: 1340436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.val = get_Dwarfish_UWord(c, cc->is_dw64); 1341436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = cc->is_dw64 ? sizeof(ULong) : sizeof(UInt); 1342436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3("0x%lx", (UWord)cts->u.val); 1343436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (0) VG_(printf)("DW_FORM_GNU_ref_alt 0x%lx\n", (UWord)cts->u.val); 1344436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (/* the following is surely impossible, but ... */ 1345436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov !ML_(sli_is_valid)(cc->escn_debug_info_alt) 1346436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov || cts->u.val >= (ULong)cc->escn_debug_info_alt.szB) { 1347663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Hmm. Offset is nonsensical for this object's .debug_info 1348663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng section. Be safe and reject it. */ 1349663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc->barf("get_Form_contents: DW_FORM_ref_addr points " 1350663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "outside alternate .debug_info"); 1351663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1352663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1353663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1354663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case DW_FORM_GNU_strp_alt: { 1355663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* this is an offset into alternate .debug_str */ 1356436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov SizeT uw = (UWord)get_Dwarfish_UWord( c, cc->is_dw64 ); 1357436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (!ML_(sli_is_valid)(cc->escn_debug_str_alt) 1358436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov || uw >= cc->escn_debug_str_alt.szB) 1359663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc->barf("get_Form_contents: DW_FORM_GNU_strp_alt " 1360663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "points outside alternate .debug_str"); 1361663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* FIXME: check the entire string lies inside debug_str, 1362663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng not just the first byte of it. */ 1363436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiCursor str 1364436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = ML_(cur_plus)( ML_(cur_from_sli)(cc->escn_debug_str_alt), uw); 1365436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (td3) { 1366436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HChar* tmp = ML_(cur_read_strdup)(str, "di.getFC.3"); 1367436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3("(indirect alt string, offset: 0x%lx): %s", uw, tmp); 1368436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ML_(dinfo_free)(tmp); 1369436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1370436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.cur = str; 1371436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->szB = - (Long)(1 + (ULong)ML_(cur_strlen)(str)); 1372663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 1373663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 1374663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 1375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 1376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)( 1377436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "get_Form_contents: unhandled %d (%s) at <%llx>\n", 1378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown form, ML_(pp_DW_FORM)(form), get_position_of_Cursor(c)); 1379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c->barf("get_Form_contents: unhandled DW_FORM"); 1380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 1385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 1386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Parsing of variable-related DIEs ---*/ 1387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 1388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 1389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 1391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct _TempVar { 1392436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HChar* name; /* in DebugInfo's .strchunks */ 1393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Represent ranges economically. nRanges is the number of 1394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ranges. Cases: 1395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0: .rngOneMin .rngOneMax .manyRanges are all zero 1396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1: .rngOneMin .rngOneMax hold the range; .rngMany is NULL 1397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2: .rngOneMin .rngOneMax are zero; .rngMany holds the ranges. 1398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This is merely an optimisation to avoid having to allocate 1399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and free the XArray in the common (98%) of cases where there 1400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is zero or one address ranges. */ 1401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord nRanges; 1402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr rngOneMin; 1403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr rngOneMax; 1404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* rngMany; /* of AddrRange. NON-UNIQUE PTR in AR_DINFO. */ 1405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Do not free .rngMany, since many TempVars will have the same 1406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown value. Instead the associated storage is to be freed by 1407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown deleting 'rangetree', which stores a single copy of each 1408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown range. */ 1409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- */ 1410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int level; 1411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord typeR; /* a cuOff */ 1412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GExpr* gexpr; /* for this variable */ 1413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GExpr* fbGX; /* to find the frame base of the enclosing fn, if 1414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown any */ 1415436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HChar* fName; /* declaring file name, or NULL */ 1416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int fLine; /* declaring file line number, or zero */ 1417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* offset in .debug_info, so that abstract instances can be 1418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown found to satisfy references from concrete instances. */ 1419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord dioff; 1420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord absOri; /* so the absOri fields refer to dioff fields 1421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in some other, related TempVar. */ 1422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TempVar; 1424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define N_D3_VAR_STACK 48 1426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 1428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 1429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Contains the range stack: a stack of address ranges, one 1430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stack entry for each nested scope. 1431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Some scope entries are created by function definitions 1433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (DW_AT_subprogram), and for those, we also note the GExpr 1434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown derived from its DW_AT_frame_base attribute, if any. 1435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Consequently it should be possible to find, for any 1436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown variable's DIE, the GExpr for the the containing function's 1437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_frame_base by scanning back through the stack to find 1438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the nearest entry associated with a function. This somewhat 1439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown elaborate scheme is provided so as to make it possible to 1440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown obtain the correct DW_AT_frame_base expression even in the 1441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown presence of nested functions (or to be more precise, in the 1442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown presence of nested DW_AT_subprogram DIEs). 1443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int sp; /* [sp] is innermost active entry; sp==-1 for empty 1445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stack */ 1446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* ranges[N_D3_VAR_STACK]; /* XArray of AddrRange */ 1447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int level[N_D3_VAR_STACK]; /* D3 DIE levels */ 1448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool isFunc[N_D3_VAR_STACK]; /* from DW_AT_subprogram? */ 1449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GExpr* fbGX[N_D3_VAR_STACK]; /* if isFunc, contains the FB 1450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown expr, else NULL */ 1451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* The file name table. Is a mapping from integer index to the 1452436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov (permanent) copy of the string in in DebugInfo's .strchunks. */ 1453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* /* of UChar* */ filenameTable; 1454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown D3VarParser; 1456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1457436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void varstack_show ( D3VarParser* parser, const HChar* str ) { 1458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word i, j; 1459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)(" varstack (%s) {\n", str); 1460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i <= parser->sp; i++) { 1461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* xa = parser->ranges[i]; 1462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(xa); 1463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)(" [%ld] (level %d)", i, parser->level[i]); 1464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (parser->isFunc[i]) { 1465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)(" (fbGX=%p)", parser->fbGX[i]); 1466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 1467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->fbGX[i] == NULL); 1468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)(": "); 1470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(sizeXA)( xa ) == 0) { 1471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("** empty PC range array **"); 1472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 1473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = 0; j < VG_(sizeXA)( xa ); j++) { 1474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddrRange* range = (AddrRange*) VG_(indexXA)( xa, j ); 1475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(range); 1476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("[%#lx,%#lx] ", range->aMin, range->aMax); 1477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("\n"); 1480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)(" }\n"); 1482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Remove from the stack, all entries with .level > 'level' */ 1485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 1486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid varstack_preen ( D3VarParser* parser, Bool td3, Int level ) 1487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool changed = False; 1489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->sp < N_D3_VAR_STACK); 1490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 1491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->sp >= -1); 1492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (parser->sp == -1) break; 1493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (parser->level[parser->sp] <= level) break; 1494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) 1495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("BBBBAAAA varstack_pop [newsp=%d]\n", parser->sp-1); 1496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->ranges[parser->sp]); 1497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Who allocated this xa? get_range_list() or 1498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unitary_range_list(). */ 1499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(deleteXA)( parser->ranges[parser->sp] ); 1500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->ranges[parser->sp] = NULL; 1501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->level[parser->sp] = 0; 1502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->isFunc[parser->sp] = False; 1503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->fbGX[parser->sp] = NULL; 1504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->sp--; 1505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown changed = True; 1506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (changed && td3) 1508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varstack_show( parser, "after preen" ); 1509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void varstack_push ( CUConst* cc, 1512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown D3VarParser* parser, 1513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool td3, 1514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* ranges, Int level, 1515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool isFunc, GExpr* fbGX ) { 1516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) 1517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("BBBBAAAA varstack_push[newsp=%d]: %d %p\n", 1518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->sp+1, level, ranges); 1519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* First we need to zap everything >= 'level', as we are about to 1521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown replace any previous entry at 'level', so .. */ 1522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varstack_preen(parser, /*td3*/False, level-1); 1523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->sp >= -1); 1525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->sp < N_D3_VAR_STACK); 1526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (parser->sp == N_D3_VAR_STACK-1) 1527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf("varstack_push: N_D3_VAR_STACK is too low; " 1528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "increase and recompile"); 1529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (parser->sp >= 0) 1530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->level[parser->sp] < level); 1531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->sp++; 1532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->ranges[parser->sp] == NULL); 1533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->level[parser->sp] == 0); 1534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->isFunc[parser->sp] == False); 1535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->fbGX[parser->sp] == NULL); 1536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ranges != NULL); 1537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!isFunc) vg_assert(fbGX == NULL); 1538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->ranges[parser->sp] = ranges; 1539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->level[parser->sp] = level; 1540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->isFunc[parser->sp] = isFunc; 1541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->fbGX[parser->sp] = fbGX; 1542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (td3) 1543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varstack_show( parser, "after push" ); 1544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1547436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* cts is derived from a DW_AT_location and so refers either to a 1548436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov location expression or to a location list. Figure out which, and 1549436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov in both cases bundle the expression or location list into a 1550436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov so-called GExpr (guarded expression). */ 1551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline)) 1552436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic GExpr* get_GX ( CUConst* cc, Bool td3, const FormContents* cts ) 1553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GExpr* gexpr = NULL; 1555436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (cts->szB < 0) { 1556436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* represents a non-empty in-line location expression, and 1557436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cts->u.cur points at the image bytes */ 1558436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov gexpr = make_singleton_GX( cts->u.cur, (ULong)(- cts->szB) ); 1559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 1561436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (cts->szB > 0) { 1562436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* represents a location list. cts->u.val is the offset of it 1563436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov in .debug_loc. */ 1564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!cc->cu_svma_known) 1565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf("get_GX: location list, but CU svma is unknown"); 1566436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov gexpr = make_general_GX( cc, td3, cts->u.val, cc->cu_svma ); 1567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 1569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(0); /* else caller is bogus */ 1570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return gexpr; 1572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 1576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid read_filename_table( /*MOD*/D3VarParser* parser, 1577436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov CUConst* cc, ULong debug_line_offset, 1578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool td3 ) 1579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool is_dw64; 1581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Cursor c; 1582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word i; 1583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UShort version; 1584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar opcode_base; 1585436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HChar* str; 1586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser && cc && cc->barf); 1588436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (!ML_(sli_is_valid)(cc->escn_debug_line) 1589436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov || cc->escn_debug_line.szB <= debug_line_offset) { 1590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf("read_filename_table: .debug_line is missing?"); 1591436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1593436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov init_Cursor( &c, cc->escn_debug_line, debug_line_offset, cc->barf, 1594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "Overrun whilst reading .debug_line section(1)" ); 1595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* unit_length = */ 1597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown get_Initial_Length( &is_dw64, &c, 1598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "read_filename_table: invalid initial-length field" ); 1599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown version = get_UShort( &c ); 1600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (version != 2 && version != 3 && version != 4) 1601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf("read_filename_table: Only DWARF version 2, 3 and 4 line info " 1602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "is currently supported."); 1603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*header_length = (ULong)*/ get_Dwarfish_UWord( &c, is_dw64 ); 1604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*minimum_instruction_length = */ get_UChar( &c ); 1605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (version >= 4) 1606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*maximum_operations_per_insn = */ get_UChar( &c ); 1607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*default_is_stmt = */ get_UChar( &c ); 1608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*line_base = (Char)*/ get_UChar( &c ); 1609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*line_range = */ get_UChar( &c ); 1610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown opcode_base = get_UChar( &c ); 1611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* skip over "standard_opcode_lengths" */ 1612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 1; i < (Word)opcode_base; i++) 1613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void)get_UChar( &c ); 1614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* skip over the directory names table */ 1616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (peek_UChar(&c) != 0) { 1617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void)get_AsciiZ(&c); 1618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void)get_UChar(&c); /* skip terminating zero */ 1620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Read and record the file names table */ 1622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->filenameTable); 1623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert( VG_(sizeXA)( parser->filenameTable ) == 0 ); 1624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Add a dummy index-zero entry. DWARF3 numbers its files 1625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown from 1, for some reason. */ 1626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown str = ML_(addStr)( cc->di, "<unknown_file>", -1 ); 1627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToXA)( parser->filenameTable, &str ); 1628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (peek_UChar(&c) != 0) { 1629436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiCursor cur = get_AsciiZ(&c); 1630436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov str = ML_(addStrFromCursor)( cc->di, cur ); 1631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" read_filename_table: %ld %s\n", 1632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sizeXA)(parser->filenameTable), str); 1633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToXA)( parser->filenameTable, &str ); 1634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void)get_ULEB128( &c ); /* skip directory index # */ 1635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void)get_ULEB128( &c ); /* skip last mod time */ 1636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void)get_ULEB128( &c ); /* file size */ 1637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* We're done! The rest of it is not interesting. */ 1639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 1640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1641eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov__attribute__((noinline)) 1642eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanovstatic void bad_DIE_confusion(int linenr) 1643eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov{ 1644eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov VG_(printf)("\nparse_var_DIE(%d): confused by:\n", linenr); 1645eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov} 1646eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov#define goto_bad_DIE do {bad_DIE_confusion(__LINE__); goto bad_DIE;} while (0) 1647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline)) 1649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void parse_var_DIE ( 1650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/WordFM* /* of (XArray* of AddrRange, void) */ rangestree, 1651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/XArray* /* of TempVar* */ tempvars, 1652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/XArray* /* of GExpr* */ gexprs, 1653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/D3VarParser* parser, 1654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_TAG dtag, 1655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord posn, 1656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int level, 1657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Cursor* c_die, 1658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Cursor* c_abbv, 1659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CUConst* cc, 1660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool td3 1661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown) 1662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 1663436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov FormContents cts; 1664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord saved_die_c_offset = get_position_of_Cursor( c_die ); 1666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord saved_abbv_c_offset = get_position_of_Cursor( c_abbv ); 1667663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool debug_types_flag; 1668663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool alt_flag; 1669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varstack_preen( parser, td3, level-1 ); 1671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1672663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (dtag == DW_TAG_compile_unit 1673663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || dtag == DW_TAG_type_unit 1674663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || dtag == DW_TAG_partial_unit) { 1675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool have_lo = False; 1676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool have_hi1 = False; 1677663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool hiIsRelative = False; 1678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool have_range = False; 1679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr ip_lo = 0; 1680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr ip_hi1 = 0; 1681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr rangeoff = 0; 1682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 1683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT attr = (DW_AT) get_ULEB128( c_abbv ); 1684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_FORM form = (DW_FORM)get_ULEB128( c_abbv ); 1685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (attr == 0 && form == 0) break; 1686436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); 1687436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_low_pc && cts.szB > 0) { 1688436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ip_lo = cts.u.val; 1689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown have_lo = True; 1690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1691436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_high_pc && cts.szB > 0) { 1692436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ip_hi1 = cts.u.val; 1693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown have_hi1 = True; 1694663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (form != DW_FORM_addr) 1695663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng hiIsRelative = True; 1696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1697436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_ranges && cts.szB > 0) { 1698436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov rangeoff = cts.u.val; 1699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown have_range = True; 1700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1701436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_stmt_list && cts.szB > 0) { 1702436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov read_filename_table( parser, cc, cts.u.val, td3 ); 1703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1705663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (have_lo && have_hi1 && hiIsRelative) 1706663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ip_hi1 += ip_lo; 1707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Now, does this give us an opportunity to find this 1708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CU's svma? */ 1709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0 1710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (level == 0 && have_lo) { 1711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(!cc->cu_svma_known); /* if this fails, it must be 1712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown because we've already seen a DW_TAG_compile_unit DIE at level 1713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0. But that can't happen, because DWARF3 only allows exactly 1714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown one top level DIE per CU. */ 1715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->cu_svma_known = True; 1716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->cu_svma = ip_lo; 1717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (1) 1718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("BBBBAAAA acquire CU_SVMA of %p\n", cc->cu_svma); 1719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Now, it may be that this DIE doesn't tell us the CU's 1720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SVMA, by way of not having a DW_AT_low_pc. That's OK -- 1721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the CU doesn't *have* to have its SVMA specified. 1722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown But as per last para D3 spec sec 3.1.1 ("Normal and 1724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Partial Compilation Unit Entries", "If the base address 1725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (viz, the SVMA) is undefined, then any DWARF entry of 1726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown structure defined interms of the base address of that 1727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown compilation unit is not valid.". So that means, if whilst 1728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown processing the children of this top level DIE (or their 1729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown children, etc) we see a DW_AT_range, and cu_svma_known is 1730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown False, then the DIE that contains it is (per the spec) 1731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown invalid, and we can legitimately stop and complain. */ 1732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 1734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* .. whereas The Reality is, simply assume the SVMA is zero 1735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if it isn't specified. */ 1736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (level == 0) { 1737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(!cc->cu_svma_known); 1738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->cu_svma_known = True; 1739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (have_lo) 1740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->cu_svma = ip_lo; 1741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 1742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->cu_svma = 0; 1743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 1745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Do we have something that looks sane? */ 1746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (have_lo && have_hi1 && (!have_range)) { 1747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ip_lo < ip_hi1) 1748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varstack_push( cc, parser, td3, 1749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unitary_range_list(ip_lo, ip_hi1 - 1), 1750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown level, 1751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown False/*isFunc*/, NULL/*fbGX*/ ); 1752eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov else if (ip_lo == 0 && ip_hi1 == 0) 1753eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov /* CU has no code, presumably? 1754eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov Such situations have been encountered for code 1755eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov compiled with -ffunction-sections -fdata-sections 1756eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov and linked with --gc-sections. Completely 1757eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov eliminated CU gives such 0 lo/hi pc. Similarly 1758eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov to a CU which has no lo/hi/range pc, we push 1759eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov an empty range list. */ 1760eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov varstack_push( cc, parser, td3, 1761eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov empty_range_list(), 1762eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov level, 1763eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov False/*isFunc*/, NULL/*fbGX*/ ); 1764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else 1765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((!have_lo) && (!have_hi1) && have_range) { 1766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varstack_push( cc, parser, td3, 1767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown get_range_list( cc, td3, 1768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rangeoff, cc->cu_svma ), 1769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown level, 1770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown False/*isFunc*/, NULL/*fbGX*/ ); 1771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else 1772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((!have_lo) && (!have_hi1) && (!have_range)) { 1773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* CU has no code, presumably? */ 1774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varstack_push( cc, parser, td3, 1775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown empty_range_list(), 1776ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown level, 1777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown False/*isFunc*/, NULL/*fbGX*/ ); 1778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else 1779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (have_lo && (!have_hi1) && have_range && ip_lo == 0) { 1780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* broken DIE created by gcc-4.3.X ? Ignore the 1781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown apparently-redundant DW_AT_low_pc and use the DW_AT_ranges 1782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown instead. */ 1783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varstack_push( cc, parser, td3, 1784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown get_range_list( cc, td3, 1785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rangeoff, cc->cu_svma ), 1786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown level, 1787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown False/*isFunc*/, NULL/*fbGX*/ ); 1788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 1789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) VG_(printf)("I got hlo %d hhi1 %d hrange %d\n", 1790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (Int)have_lo, (Int)have_hi1, (Int)have_range); 1791eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov goto_bad_DIE; 1792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dtag == DW_TAG_lexical_block || dtag == DW_TAG_subprogram) { 1796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool have_lo = False; 1797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool have_hi1 = False; 1798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool have_range = False; 1799663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool hiIsRelative = False; 1800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr ip_lo = 0; 1801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr ip_hi1 = 0; 1802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr rangeoff = 0; 1803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool isFunc = dtag == DW_TAG_subprogram; 1804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GExpr* fbGX = NULL; 1805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 1806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT attr = (DW_AT) get_ULEB128( c_abbv ); 1807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_FORM form = (DW_FORM)get_ULEB128( c_abbv ); 1808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (attr == 0 && form == 0) break; 1809436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); 1810436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_low_pc && cts.szB > 0) { 1811436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ip_lo = cts.u.val; 1812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown have_lo = True; 1813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1814436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_high_pc && cts.szB > 0) { 1815436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ip_hi1 = cts.u.val; 1816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown have_hi1 = True; 1817663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (form != DW_FORM_addr) 1818663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng hiIsRelative = True; 1819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1820436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_ranges && cts.szB > 0) { 1821436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov rangeoff = cts.u.val; 1822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown have_range = True; 1823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (isFunc 1825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && attr == DW_AT_frame_base 1826436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov && cts.szB != 0 /* either scalar or nonempty block */) { 1827436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fbGX = get_GX( cc, False/*td3*/, &cts ); 1828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(fbGX); 1829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToXA)(gexprs, &fbGX); 1830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1832663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (have_lo && have_hi1 && hiIsRelative) 1833663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ip_hi1 += ip_lo; 1834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Do we have something that looks sane? */ 1835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dtag == DW_TAG_subprogram 1836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && (!have_lo) && (!have_hi1) && (!have_range)) { 1837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This is legit - ignore it. Sec 3.3.3: "A subroutine entry 1838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown representing a subroutine declaration that is not also a 1839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown definition does not have code address or range 1840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown attributes." */ 1841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else 1842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dtag == DW_TAG_lexical_block 1843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && (!have_lo) && (!have_hi1) && (!have_range)) { 1844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* I believe this is legit, and means the lexical block 1845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown contains no insns (whatever that might mean). Ignore. */ 1846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else 1847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (have_lo && have_hi1 && (!have_range)) { 1848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This scope supplies just a single address range. */ 1849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ip_lo < ip_hi1) 1850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varstack_push( cc, parser, td3, 1851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unitary_range_list(ip_lo, ip_hi1 - 1), 1852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown level, isFunc, fbGX ); 1853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else 1854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((!have_lo) && (!have_hi1) && have_range) { 1855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This scope supplies multiple address ranges via the use of 1856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a range list. */ 1857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varstack_push( cc, parser, td3, 1858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown get_range_list( cc, td3, 1859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rangeoff, cc->cu_svma ), 1860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown level, isFunc, fbGX ); 1861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else 1862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (have_lo && (!have_hi1) && (!have_range)) { 1863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This scope is bogus. The D3 spec sec 3.4 (Lexical Block 1864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Entries) says fairly clearly that a scope must have either 1865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown _range or (_low_pc and _high_pc). */ 1866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* The spec is a bit ambiguous though. Perhaps a single byte 1867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown range is intended? See sec 2.17 (Code Addresses And Ranges) */ 1868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This case is here because icc9 produced this: 1869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <2><13bd>: DW_TAG_lexical_block 1870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_decl_line : 5229 1871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_decl_column : 37 1872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_decl_file : 1 1873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_low_pc : 0x401b03 1874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Ignore (seems safe than pushing a single byte range) */ 1876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else 1877eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov goto_bad_DIE; 1878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dtag == DW_TAG_variable || dtag == DW_TAG_formal_parameter) { 1881436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HChar* name = NULL; 1882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord typeR = D3_INVALID_CUOFF; 1883436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Bool global = False; 1884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GExpr* gexpr = NULL; 1885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int n_attrs = 0; 1886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord abs_ori = (UWord)D3_INVALID_CUOFF; 1887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int lineNo = 0; 1888436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov HChar* fileName = NULL; 1889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 1890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT attr = (DW_AT) get_ULEB128( c_abbv ); 1891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_FORM form = (DW_FORM)get_ULEB128( c_abbv ); 1892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (attr == 0 && form == 0) break; 1893436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); 1894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n_attrs++; 1895436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_name && cts.szB < 0) { 1896436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov name = ML_(addStrFromCursor)( cc->di, cts.u.cur ); 1897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (attr == DW_AT_location 1899436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov && cts.szB != 0 /* either scalar or nonempty block */) { 1900436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov gexpr = get_GX( cc, False/*td3*/, &cts ); 1901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(gexpr); 1902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToXA)(gexprs, &gexpr); 1903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1904436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_type && cts.szB > 0) { 1905436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov typeR = cook_die_using_form( cc, cts.u.val, form ); 1906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1907436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_external && cts.szB > 0 && cts.u.val > 0) { 1908436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov global = True; 1909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1910436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_abstract_origin && cts.szB > 0) { 1911436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov abs_ori = (UWord)cts.u.val; 1912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1913436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_declaration && cts.szB > 0 && cts.u.val > 0) { 1914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*declaration = True;*/ 1915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1916436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_decl_line && cts.szB > 0) { 1917436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov lineNo = (Int)cts.u.val; 1918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1919436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_decl_file && cts.szB > 0) { 1920436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int ftabIx = (Int)cts.u.val; 1921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ftabIx >= 1 1922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && ftabIx < VG_(sizeXA)( parser->filenameTable )) { 1923436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fileName = *(HChar**) 1924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(indexXA)( parser->filenameTable, ftabIx ); 1925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(fileName); 1926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) VG_(printf)("XXX filename = %s\n", fileName); 1928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1930436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (!global && dtag == DW_TAG_variable && level == 1) { 1931436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Case of a static variable. It is better to declare 1932436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov it global as the variable is not really related to 1933436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov a PC range, as its address can be used by program 1934436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov counters outside of the ranges where it is visible . */ 1935436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov global = True; 1936436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 1937436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 1938ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* We'll collect it under if one of the following three 1939ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown conditions holds: 1940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (1) has location and type -> completed 1941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (2) has type only -> is an abstract instance 1942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (3) has location and abs_ori -> is a concrete instance 1943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Name, filename and line number are all optional frills. 1944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 1945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ( /* 1 */ (gexpr && typeR != D3_INVALID_CUOFF) 1946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 2 */ || (typeR != D3_INVALID_CUOFF) 1947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* 3 */ || (gexpr && abs_ori != (UWord)D3_INVALID_CUOFF) ) { 1948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Add this variable to the list of interesting looking 1950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown variables. Crucially, note along with it the address 1951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown range(s) associated with the variable, which for locals 1952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown will be the address ranges at the top of the varparser's 1953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stack. */ 1954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GExpr* fbGX = NULL; 1955ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word i, nRanges; 1956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* /* of AddrRange */ xa; 1957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TempVar* tv; 1958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Stack can't be empty; we put a dummy entry on it for the 1959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown entire address range before starting with the DIEs for 1960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown this CU. */ 1961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->sp >= 0); 1962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 1963436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* If this is a local variable (non-global), try to find 1964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the GExpr for the DW_AT_frame_base of the containing 1965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown function. It should have been pushed on the stack at the 1966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown time we encountered its DW_TAG_subprogram DIE, so the way 1967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to find it is to scan back down the stack looking for it. 1968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown If there isn't an enclosing stack entry marked 'isFunc' 1969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown then we must be seeing variable or formal param DIEs 1970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown outside of a function, so we deem the Dwarf to be 1971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown malformed if that happens. Note that the fbGX may be NULL 1972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if the containing DT_TAG_subprogram didn't supply a 1973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_frame_base -- that's OK, but there must actually be 1974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a containing DW_TAG_subprogram. */ 1975436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (!global) { 1976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool found = False; 1977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = parser->sp; i >= 0; i--) { 1978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (parser->isFunc[i]) { 1979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fbGX = parser->fbGX[i]; 1980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown found = True; 1981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 1982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!found) { 1985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0 && VG_(clo_verbosity) >= 0) { 1986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_DebugMsg, 1987436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "warning: parse_var_DIE: non-global variable " 1988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "outside DW_TAG_subprogram\n"); 1989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1990eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov /* goto_bad_DIE; */ 1991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This seems to happen a lot. Just ignore it -- if, 1992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown when we come to evaluation of the location (guarded) 1993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown expression, it requires a frame base value, and 1994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown there's no expression for that, then evaluation as a 1995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown whole will fail. Harmless - a bit of a waste of 1996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cycles but nothing more. */ 1997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 1999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2000436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* re "global ? 0 : parser->sp" (twice), if the var is 2001436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov marked 'global' then we must put it at the global scope, 2002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown as only the global scope (level 0) covers the entire PC 2003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown address space. It is asserted elsewhere that level 0 2004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown always covers the entire address space. */ 2005436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov xa = parser->ranges[global ? 0 : parser->sp]; 2006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown nRanges = VG_(sizeXA)(xa); 2007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(nRanges >= 0); 2008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tv = ML_(dinfo_zalloc)( "di.readdwarf3.pvD.1", sizeof(TempVar) ); 2010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tv->name = name; 2011436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tv->level = global ? 0 : parser->sp; 2012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tv->typeR = typeR; 2013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tv->gexpr = gexpr; 2014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tv->fbGX = fbGX; 2015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tv->fName = fileName; 2016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tv->fLine = lineNo; 2017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tv->dioff = posn; 2018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tv->absOri = abs_ori; 2019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* See explanation on definition of type TempVar for the 2021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown reason for this elaboration. */ 2022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tv->nRanges = nRanges; 2023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tv->rngOneMin = 0; 2024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tv->rngOneMax = 0; 2025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tv->rngMany = NULL; 2026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (nRanges == 1) { 2027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddrRange* range = VG_(indexXA)(xa, 0); 2028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tv->rngOneMin = range->aMin; 2029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tv->rngOneMax = range->aMax; 2030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (nRanges > 1) { 2032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* See if we already have a range list which is 2033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown structurally identical. If so, use that; if not, clone 2034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown this one, and add it to our collection. */ 2035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord keyW, valW; 2036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(lookupFM)( rangestree, &keyW, &valW, (UWord)xa )) { 2037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* old = (XArray*)keyW; 2038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(valW == 0); 2039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tl_assert(old != xa); 2040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tv->rngMany = old; 2041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 2042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* cloned = VG_(cloneXA)( "di.readdwarf3.pvD.2", xa ); 2043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tv->rngMany = cloned; 2044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToFM)( rangestree, (UWord)cloned, 0 ); 2045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToXA)( tempvars, &tv ); 2049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" Recording this variable, with %ld PC range(s)\n", 2051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sizeXA)(xa) ); 2052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* collect stats on how effective the ->ranges special 2053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown casing is */ 2054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) { 2055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown static Int ntot=0, ngt=0; 2056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ntot++; 2057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (tv->rngMany) ngt++; 2058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0 == (ntot % 100000)) 2059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("XXXX %d tot, %d cloned\n", ntot, ngt); 2060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Here are some other weird cases seen in the wild: 2065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown We have a variable with a name and a type, but no 2067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown location. I guess that's a sign that it has been 2068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown optimised away. Ignore it. Here's an example: 2069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown static Int lc_compar(void* n1, void* n2) { 2071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Chunk* mc1 = *(MC_Chunk**)n1; 2072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MC_Chunk* mc2 = *(MC_Chunk**)n2; 2073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (mc1->data < mc2->data ? -1 : 1); 2074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Both mc1 and mc2 are like this 2077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <2><5bc>: Abbrev Number: 21 (DW_TAG_variable) 2078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_name : mc1 2079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_decl_file : 1 2080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_decl_line : 216 2081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_type : <5d3> 2082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown whereas n1 and n2 do have locations specified. 2084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --------------------------------------------- 2086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown We see a DW_TAG_formal_parameter with a type, but 2088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown no name and no location. It's probably part of a function type 2089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown construction, thusly, hence ignore it: 2090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <1><2b4>: Abbrev Number: 12 (DW_TAG_subroutine_type) 2091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_sibling : <2c9> 2092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_prototyped : 1 2093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_type : <114> 2094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <2><2be>: Abbrev Number: 13 (DW_TAG_formal_parameter) 2095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_type : <13e> 2096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <2><2c3>: Abbrev Number: 13 (DW_TAG_formal_parameter) 2097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_type : <133> 2098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --------------------------------------------- 2100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Is very minimal, like this: 2102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <4><81d>: Abbrev Number: 44 (DW_TAG_variable) 2103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_abstract_origin: <7ba> 2104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown What that signifies I have no idea. Ignore. 2105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ---------------------------------------------- 2107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Is very minimal, like this: 2109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <200f>: DW_TAG_formal_parameter 2110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_abstract_ori: <1f4c> 2111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_location : 13440 2112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown What that signifies I have no idea. Ignore. 2113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown It might be significant, though: the variable at least 2114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown has a location and so might exist somewhere. 2115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Maybe we should handle this. 2116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown --------------------------------------------- 2118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <22407>: DW_TAG_variable 2120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_name : (indirect string, offset: 0x6579): 2121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vgPlain_trampoline_stuff_start 2122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_decl_file : 29 2123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_decl_line : 56 2124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_external : 1 2125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_declaration : 1 2126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Nameless and typeless variable that has a location? Who 2128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown knows. Not me. 2129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <2><3d178>: Abbrev Number: 22 (DW_TAG_variable) 2130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_location : 9 byte block: 3 c0 c7 13 38 0 0 0 0 2131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (DW_OP_addr: 3813c7c0) 2132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown No, really. Check it out. gcc is quite simply borked. 2134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <3><168cc>: Abbrev Number: 141 (DW_TAG_variable) 2135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // followed by no attributes, and the next DIE is a sibling, 2136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // not a child 2137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 2138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 2140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bad_DIE: 2142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set_position_of_Cursor( c_die, saved_die_c_offset ); 2143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set_position_of_Cursor( c_abbv, saved_abbv_c_offset ); 2144663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng posn = uncook_die( cc, posn, &debug_types_flag, &alt_flag ); 2145663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(printf)(" <%d><%lx>: %s", level, posn, ML_(pp_DW_TAG)( dtag ) ); 2146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (debug_types_flag) { 2147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(printf)(" (in .debug_types)"); 2148663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2149663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else if (alt_flag) { 2150663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(printf)(" (in alternate .debug_info)"); 2151663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2152663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(printf)("\n"); 2153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 2154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT attr = (DW_AT) get_ULEB128( c_abbv ); 2155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_FORM form = (DW_FORM)get_ULEB128( c_abbv ); 2156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (attr == 0 && form == 0) break; 2157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)(" %18s: ", ML_(pp_DW_AT)(attr)); 2158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Get the form contents, so as to print them */ 2159436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov get_Form_contents( &cts, cc, c_die, True, form ); 2160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("\t\n"); 2161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("\n"); 2163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf("parse_var_DIE: confused by the above DIE"); 2164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ 2165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 2169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 2170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Parsing of type-related DIEs ---*/ 2171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 2172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 2173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define N_D3_TYPE_STACK 16 2175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 2177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 2178f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* What source language? 'A'=Ada83/95, 2179f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 'C'=C/C++, 2180f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root 'F'=Fortran, 2181f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root '?'=other 2182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Established once per compilation unit. */ 2183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar language; 2184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* A stack of types which are currently under construction */ 2185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int sp; /* [sp] is innermost active entry; sp==-1 for empty 2186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stack */ 2187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Note that the TyEnts in qparentE are temporary copies of the 2188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ones accumulating in the main tyent array. So it is not safe 2189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to free up anything on them when popping them off the stack 2190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (iow, it isn't safe to use TyEnt__make_EMPTY on them). Just 2191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown memset them to zero when done. */ 2192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEnt qparentE[N_D3_TYPE_STACK]; /* parent TyEnts */ 2193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int qlevel[N_D3_TYPE_STACK]; 2194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown D3TypeParser; 2197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2198436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void typestack_show ( D3TypeParser* parser, const HChar* str ) { 2199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word i; 2200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)(" typestack (%s) {\n", str); 2201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i <= parser->sp; i++) { 2202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)(" [%ld] (level %d): ", i, parser->qlevel[i]); 2203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(pp_TyEnt)( &parser->qparentE[i] ); 2204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("\n"); 2205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)(" }\n"); 2207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Remove from the stack, all entries with .level > 'level' */ 2210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 2211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid typestack_preen ( D3TypeParser* parser, Bool td3, Int level ) 2212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool changed = False; 2214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->sp < N_D3_TYPE_STACK); 2215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 2216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->sp >= -1); 2217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (parser->sp == -1) break; 2218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (parser->qlevel[parser->sp] <= level) break; 2219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) 2220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("BBBBAAAA typestack_pop [newsp=%d]\n", parser->sp-1); 2221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp])); 2222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(&parser->qparentE[parser->sp], 0, sizeof(TyEnt)); 2223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->qparentE[parser->sp].cuOff = D3_INVALID_CUOFF; 2224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->qparentE[parser->sp].tag = Te_EMPTY; 2225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->qlevel[parser->sp] = 0; 2226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->sp--; 2227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown changed = True; 2228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (changed && td3) 2230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typestack_show( parser, "after preen" ); 2231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool typestack_is_empty ( D3TypeParser* parser ) { 2234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->sp >= -1 && parser->sp < N_D3_TYPE_STACK); 2235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return parser->sp == -1; 2236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void typestack_push ( CUConst* cc, 2239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown D3TypeParser* parser, 2240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool td3, 2241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEnt* parentE, Int level ) { 2242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) 2243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("BBBBAAAA typestack_push[newsp=%d]: %d %05lx\n", 2244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->sp+1, level, parentE->cuOff); 2245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* First we need to zap everything >= 'level', as we are about to 2247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown replace any previous entry at 'level', so .. */ 2248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typestack_preen(parser, /*td3*/False, level-1); 2249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->sp >= -1); 2251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->sp < N_D3_TYPE_STACK); 2252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (parser->sp == N_D3_TYPE_STACK-1) 2253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf("typestack_push: N_D3_TYPE_STACK is too low; " 2254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "increase and recompile"); 2255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (parser->sp >= 0) 2256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->qlevel[parser->sp] < level); 2257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->sp++; 2258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->qparentE[parser->sp].tag == Te_EMPTY); 2259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->qlevel[parser->sp] == 0); 2260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parentE); 2261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ML_(TyEnt__is_type)(parentE)); 2262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parentE->cuOff != D3_INVALID_CUOFF); 2263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->qparentE[parser->sp] = *parentE; 2264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->qlevel[parser->sp] = level; 2265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (td3) 2266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typestack_show( parser, "after push" ); 2267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 2268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2269f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root/* True if the subrange type being parsed gives the bounds of an array. */ 2270f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Rootstatic Bool subrange_type_denotes_array_bounds ( D3TypeParser* parser, 2271f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root DW_TAG dtag ) { 2272f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root vg_assert(dtag == DW_TAG_subrange_type); 2273f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* For most languages, a subrange_type dtag always gives the 2274f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root bounds of an array. 2275f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root For Ada, there are additional conditions as a subrange_type 2276f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root is also used for other purposes. */ 2277f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (parser->language != 'A') 2278f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* not Ada, so it definitely denotes an array bound. */ 2279f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root return True; 2280f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root else 2281f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* Extra constraints for Ada: it only denotes an array bound if .. */ 2282f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root return (! typestack_is_empty(parser) 2283f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root && parser->qparentE[parser->sp].tag == Te_TyArray); 2284f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root} 2285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Parse a type-related DIE. 'parser' holds the current parser state. 2287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'admin' is where the completed types are dumped. 'dtag' is the tag 2288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for this DIE. 'c_die' points to the start of the data fields (FORM 2289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stuff) for the DIE. c_abbv points to the start of the (name,form) 2290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pairs which describe the DIE. 2291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown We may find the DIE uninteresting, in which case we should ignore 2293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown it. 2294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown What happens: the DIE is examined. If uninteresting, it is ignored. 2296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Otherwise, the DIE gives rise to two things: 2297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (1) the offset of this DIE in the CU -- the cuOffset, a UWord 2299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (2) a TyAdmin structure, which holds the type, or related stuff 2300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (2) is added at the end of 'tyadmins', at some index, say 'i'. 2302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown A pair (cuOffset, i) is added to 'tydict'. 2304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Hence 'tyadmins' holds the actual type entities, and 'tydict' holds 2306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a mapping from cuOffset to the index of the corresponding entry in 2307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'tyadmin'. 2308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown When resolving a cuOffset to a TyAdmin, first look up the cuOffset 2310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in the tydict (by binary search). This gives an index into 2311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tyadmins, and the required entity lives in tyadmins at that index. 2312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 2313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline)) 2314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void parse_type_DIE ( /*MOD*/XArray* /* of TyEnt */ tyents, 2315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/D3TypeParser* parser, 2316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_TAG dtag, 2317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord posn, 2318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int level, 2319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Cursor* c_die, 2320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Cursor* c_abbv, 2321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown CUConst* cc, 2322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool td3 ) 2323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 2324436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov FormContents cts; 2325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEnt typeE; 2326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEnt atomE; 2327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEnt fieldE; 2328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEnt boundE; 2329663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool debug_types_flag; 2330663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Bool alt_flag; 2331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord saved_die_c_offset = get_position_of_Cursor( c_die ); 2333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord saved_abbv_c_offset = get_position_of_Cursor( c_abbv ); 2334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)( &typeE, 0xAA, sizeof(typeE) ); 2336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)( &atomE, 0xAA, sizeof(atomE) ); 2337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)( &fieldE, 0xAA, sizeof(fieldE) ); 2338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)( &boundE, 0xAA, sizeof(boundE) ); 2339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If we've returned to a level at or above any previously noted 2341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parent, un-note it, so we don't believe we're still collecting 2342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown its children. */ 2343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typestack_preen( parser, td3, level-1 ); 2344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2345663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (dtag == DW_TAG_compile_unit 2346663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || dtag == DW_TAG_type_unit 2347663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || dtag == DW_TAG_partial_unit) { 2348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* See if we can find DW_AT_language, since it is important for 2349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown establishing array bounds (see DW_TAG_subrange_type below in 2350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown this fn) */ 2351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 2352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT attr = (DW_AT) get_ULEB128( c_abbv ); 2353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_FORM form = (DW_FORM)get_ULEB128( c_abbv ); 2354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (attr == 0 && form == 0) break; 2355436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); 2356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (attr != DW_AT_language) 2357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 2358436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (cts.szB <= 0) 2359eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov goto_bad_DIE; 2360436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov switch (cts.u.val) { 2361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_LANG_C89: case DW_LANG_C: 2362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_LANG_C_plus_plus: case DW_LANG_ObjC: 2363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_LANG_ObjC_plus_plus: case DW_LANG_UPC: 2364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_LANG_Upc: case DW_LANG_C99: 2365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->language = 'C'; break; 2366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_LANG_Fortran77: case DW_LANG_Fortran90: 2367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_LANG_Fortran95: 2368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->language = 'F'; break; 2369f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root case DW_LANG_Ada83: case DW_LANG_Ada95: 2370f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root parser->language = 'A'; break; 2371f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root case DW_LANG_Cobol74: 2372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_LANG_Cobol85: case DW_LANG_Pascal83: 2373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_LANG_Modula2: case DW_LANG_Java: 2374f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root case DW_LANG_PLI: 2375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_LANG_D: case DW_LANG_Python: 2376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_LANG_Mips_Assembler: 2377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parser->language = '?'; break; 2378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 2379eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov goto_bad_DIE; 2380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dtag == DW_TAG_base_type) { 2385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* We can pick up a new base type any time. */ 2386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(&typeE, 0, sizeof(typeE)); 2387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.cuOff = D3_INVALID_CUOFF; 2388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.tag = Te_TyBase; 2389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 2390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT attr = (DW_AT) get_ULEB128( c_abbv ); 2391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_FORM form = (DW_FORM)get_ULEB128( c_abbv ); 2392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (attr == 0 && form == 0) break; 2393436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); 2394436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_name && cts.szB < 0) { 2395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyBase.name 2396436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = ML_(cur_read_strdup)( cts.u.cur, 2397436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "di.readdwarf3.ptD.base_type.1" ); 2398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2399436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_byte_size && cts.szB > 0) { 2400436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov typeE.Te.TyBase.szB = cts.u.val; 2401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2402436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_encoding && cts.szB > 0) { 2403436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov switch (cts.u.val) { 2404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_ATE_unsigned: case DW_ATE_unsigned_char: 2405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_ATE_UTF: /* since DWARF4, e.g. char16_t from C++ */ 2406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_ATE_boolean:/* FIXME - is this correct? */ 2407663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case DW_ATE_unsigned_fixed: 2408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyBase.enc = 'U'; break; 2409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_ATE_signed: case DW_ATE_signed_char: 2410663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case DW_ATE_signed_fixed: 2411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyBase.enc = 'S'; break; 2412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_ATE_float: 2413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyBase.enc = 'F'; break; 2414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case DW_ATE_complex_float: 2415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyBase.enc = 'C'; break; 2416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 2417eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov goto_bad_DIE; 2418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Invent a name if it doesn't have one. gcc-4.3 2423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown -ftree-vectorize is observed to emit nameless base types. */ 2424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!typeE.Te.TyBase.name) 2425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyBase.name 2426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = ML_(dinfo_strdup)( "di.readdwarf3.ptD.base_type.2", 2427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "<anon_base_type>" ); 2428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Do we have something that looks sane? */ 2430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (/* must have a name */ 2431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyBase.name == NULL 2432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* and a plausible size. Yes, really 32: "complex long 2433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown double" apparently has size=32 */ 2434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || typeE.Te.TyBase.szB < 0 || typeE.Te.TyBase.szB > 32 2435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* and a plausible encoding */ 2436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || (typeE.Te.TyBase.enc != 'U' 2437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && typeE.Te.TyBase.enc != 'S' 2438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && typeE.Te.TyBase.enc != 'F' 2439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && typeE.Te.TyBase.enc != 'C')) 2440eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov goto_bad_DIE; 2441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Last minute hack: if we see this 2442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <1><515>: DW_TAG_base_type 2443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_byte_size : 0 2444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_encoding : 5 2445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_name : void 2446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown convert it into a real Void type. */ 2447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (typeE.Te.TyBase.szB == 0 2448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown && 0 == VG_(strcmp)("void", typeE.Te.TyBase.name)) { 2449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(TyEnt__make_EMPTY)(&typeE); 2450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.tag = Te_TyVoid; 2451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyVoid.isFake = False; /* it's a real one! */ 2452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto acquire_Type; 2455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2457663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 2458663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * An example of DW_TAG_rvalue_reference_type: 2459663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * 2460663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * $ readelf --debug-dump /usr/lib/debug/usr/lib/libstdc++.so.6.0.16.debug 2461663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * <1><1014>: Abbrev Number: 55 (DW_TAG_rvalue_reference_type) 2462663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * <1015> DW_AT_byte_size : 4 2463663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * <1016> DW_AT_type : <0xe52> 2464663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 2465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dtag == DW_TAG_pointer_type || dtag == DW_TAG_reference_type 2466663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || dtag == DW_TAG_ptr_to_member_type 2467663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng || dtag == DW_TAG_rvalue_reference_type) { 2468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This seems legit for _pointer_type and _reference_type. I 2469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown don't know if rolling _ptr_to_member_type in here really is 2470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown legit, but it's better than not handling it at all. */ 2471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(&typeE, 0, sizeof(typeE)); 2472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.cuOff = D3_INVALID_CUOFF; 2473663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng switch (dtag) { 2474663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case DW_TAG_pointer_type: 2475663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng typeE.tag = Te_TyPtr; 2476663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2477663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case DW_TAG_reference_type: 2478663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng typeE.tag = Te_TyRef; 2479663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2480663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case DW_TAG_ptr_to_member_type: 2481663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng typeE.tag = Te_TyPtrMbr; 2482663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2483663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case DW_TAG_rvalue_reference_type: 2484663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng typeE.tag = Te_TyRvalRef; 2485663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 2486663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng default: 2487663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vg_assert(False); 2488663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* target type defaults to void */ 2490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyPorR.typeR = D3_FAKEVOID_CUOFF; 2491663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* These four type kinds don't *have* to specify their size, in 2492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which case we assume it's a machine word. But if they do 2493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown specify it, it must be a machine word :-) This probably 2494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown assumes that the word size of the Dwarf3 we're reading is the 2495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown same size as that on the machine. gcc appears to give a size 2496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown whereas icc9 doesn't. */ 2497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyPorR.szB = sizeof(UWord); 2498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 2499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT attr = (DW_AT) get_ULEB128( c_abbv ); 2500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_FORM form = (DW_FORM)get_ULEB128( c_abbv ); 2501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (attr == 0 && form == 0) break; 2502436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); 2503436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_byte_size && cts.szB > 0) { 2504436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov typeE.Te.TyPorR.szB = cts.u.val; 2505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2506436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_type && cts.szB > 0) { 2507436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov typeE.Te.TyPorR.typeR 2508436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = cook_die_using_form( cc, (UWord)cts.u.val, form ); 2509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Do we have something that looks sane? */ 2512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (typeE.Te.TyPorR.szB != sizeof(UWord)) 2513eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov goto_bad_DIE; 2514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 2515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto acquire_Type; 2516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dtag == DW_TAG_enumeration_type) { 2519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Create a new Type to hold the results. */ 2520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(&typeE, 0, sizeof(typeE)); 2521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.cuOff = posn; 2522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.tag = Te_TyEnum; 2523436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Bool is_decl = False; 2524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyEnum.atomRs 2525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ptD.enum_type.1", 2526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(dinfo_free), 2527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(UWord) ); 2528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 2529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT attr = (DW_AT) get_ULEB128( c_abbv ); 2530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_FORM form = (DW_FORM)get_ULEB128( c_abbv ); 2531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (attr == 0 && form == 0) break; 2532436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); 2533436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_name && cts.szB < 0) { 2534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyEnum.name 2535436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = ML_(cur_read_strdup)( cts.u.cur, 2536436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "di.readdwarf3.pTD.enum_type.2" ); 2537436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2538436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_byte_size && cts.szB > 0) { 2539436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov typeE.Te.TyEnum.szB = cts.u.val; 2540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2541436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_declaration) { 2542436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov is_decl = True; 2543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!typeE.Te.TyEnum.name) 2547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyEnum.name 2548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = ML_(dinfo_strdup)( "di.readdwarf3.pTD.enum_type.3", 2549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "<anon_enum_type>" ); 2550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Do we have something that looks sane? */ 2552f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (typeE.Te.TyEnum.szB == 0 2553f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* we must know the size */ 2554f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* but not for Ada, which uses such dummy 2555436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov enumerations as helper for gdb ada mode. 2556436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Also GCC allows incomplete enums as GNU extension. 2557436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov http://gcc.gnu.org/onlinedocs/gcc/Incomplete-Enums.html 2558436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov These are marked as DW_AT_declaration and won't have 2559436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov a size. They can only be used in declaration or as 2560436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov pointer types. You can't allocate variables or storage 2561436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov using such an enum type. (Also GCC seems to have a bug 2562436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov that will put such an enumeration_type into a .debug_types 2563436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov unit which should only contain complete types.) */ 2564436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov && (parser->language != 'A' && !is_decl)) { 2565eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov goto_bad_DIE; 2566663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 2567663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 2568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* On't stack! */ 2569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typestack_push( cc, parser, td3, &typeE, level ); 2570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto acquire_Type; 2571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* gcc (GCC) 4.4.0 20081017 (experimental) occasionally produces 2574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_TAG_enumerator with only a DW_AT_name but no 2575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_const_value. This is in violation of the Dwarf3 standard, 2576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and appears to be a new "feature" of gcc - versions 4.3.x and 2577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown earlier do not appear to do this. So accept DW_TAG_enumerator 2578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which only have a name but no value. An example: 2579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <1><180>: Abbrev Number: 6 (DW_TAG_enumeration_type) 2581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <181> DW_AT_name : (indirect string, offset: 0xda70): 2582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown QtMsgType 2583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <185> DW_AT_byte_size : 4 2584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <186> DW_AT_decl_file : 14 2585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <187> DW_AT_decl_line : 1480 2586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <189> DW_AT_sibling : <0x1a7> 2587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <2><18d>: Abbrev Number: 7 (DW_TAG_enumerator) 2588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <18e> DW_AT_name : (indirect string, offset: 0x9e18): 2589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown QtDebugMsg 2590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <2><192>: Abbrev Number: 7 (DW_TAG_enumerator) 2591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <193> DW_AT_name : (indirect string, offset: 0x1505f): 2592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown QtWarningMsg 2593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <2><197>: Abbrev Number: 7 (DW_TAG_enumerator) 2594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <198> DW_AT_name : (indirect string, offset: 0x16f4a): 2595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown QtCriticalMsg 2596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <2><19c>: Abbrev Number: 7 (DW_TAG_enumerator) 2597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <19d> DW_AT_name : (indirect string, offset: 0x156dd): 2598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown QtFatalMsg 2599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <2><1a1>: Abbrev Number: 7 (DW_TAG_enumerator) 2600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown <1a2> DW_AT_name : (indirect string, offset: 0x13660): 2601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown QtSystemMsg 2602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */ 2603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dtag == DW_TAG_enumerator) { 2604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)( &atomE, 0, sizeof(atomE) ); 2605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atomE.cuOff = posn; 2606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atomE.tag = Te_Atom; 2607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 2608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT attr = (DW_AT) get_ULEB128( c_abbv ); 2609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_FORM form = (DW_FORM)get_ULEB128( c_abbv ); 2610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (attr == 0 && form == 0) break; 2611436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); 2612436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_name && cts.szB < 0) { 2613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atomE.Te.Atom.name 2614436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = ML_(cur_read_strdup)( cts.u.cur, 2615436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "di.readdwarf3.pTD.enumerator.1" ); 2616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2617436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_const_value && cts.szB > 0) { 2618436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov atomE.Te.Atom.value = cts.u.val; 2619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atomE.Te.Atom.valueKnown = True; 2620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Do we have something that looks sane? */ 2623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (atomE.Te.Atom.name == NULL) 2624eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov goto_bad_DIE; 2625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Do we have a plausible parent? */ 2626eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov if (typestack_is_empty(parser)) goto_bad_DIE; 2627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp])); 2628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->qparentE[parser->sp].cuOff != D3_INVALID_CUOFF); 2629eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov if (level != parser->qlevel[parser->sp]+1) goto_bad_DIE; 2630eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov if (parser->qparentE[parser->sp].tag != Te_TyEnum) goto_bad_DIE; 2631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Record this child in the parent */ 2632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->qparentE[parser->sp].Te.TyEnum.atomRs); 2633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToXA)( parser->qparentE[parser->sp].Te.TyEnum.atomRs, 2634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &atomE ); 2635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* And record the child itself */ 2636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto acquire_Atom; 2637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Treat DW_TAG_class_type as if it was a DW_TAG_structure_type. I 2640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown don't know if this is correct, but it at least makes this reader 2641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown usable for gcc-4.3 produced Dwarf3. */ 2642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dtag == DW_TAG_structure_type || dtag == DW_TAG_class_type 2643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || dtag == DW_TAG_union_type) { 2644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool have_szB = False; 2645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool is_decl = False; 2646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool is_spec = False; 2647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Create a new Type to hold the results. */ 2648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(&typeE, 0, sizeof(typeE)); 2649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.cuOff = posn; 2650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.tag = Te_TyStOrUn; 2651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyStOrUn.name = NULL; 2652eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov typeE.Te.TyStOrUn.typeR = D3_INVALID_CUOFF; 2653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyStOrUn.fieldRs 2654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.pTD.struct_type.1", 2655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(dinfo_free), 2656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(UWord) ); 2657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyStOrUn.complete = True; 2658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyStOrUn.isStruct = dtag == DW_TAG_structure_type 2659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || dtag == DW_TAG_class_type; 2660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 2661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT attr = (DW_AT) get_ULEB128( c_abbv ); 2662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_FORM form = (DW_FORM)get_ULEB128( c_abbv ); 2663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (attr == 0 && form == 0) break; 2664436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); 2665436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_name && cts.szB < 0) { 2666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyStOrUn.name 2667436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = ML_(cur_read_strdup)( cts.u.cur, 2668436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "di.readdwarf3.ptD.struct_type.2" ); 2669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2670436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_byte_size && cts.szB >= 0) { 2671436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov typeE.Te.TyStOrUn.szB = cts.u.val; 2672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown have_szB = True; 2673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2674436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_declaration && cts.szB > 0 && cts.u.val > 0) { 2675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is_decl = True; 2676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2677436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_specification && cts.szB > 0 && cts.u.val > 0) { 2678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is_spec = True; 2679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2680eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov if (attr == DW_AT_signature && form == DW_FORM_ref_sig8 2681eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov && cts.szB > 0) { 2682eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov have_szB = True; 2683eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov typeE.Te.TyStOrUn.szB = 8; 2684eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov typeE.Te.TyStOrUn.typeR 2685eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov = cook_die_using_form( cc, (UWord)cts.u.val, form ); 2686eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov } 2687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Do we have something that looks sane? */ 2689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_decl && (!is_spec)) { 2690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* It's a DW_AT_declaration. We require the name but 2691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown nothing else. */ 2692663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* JRS 2012-06-28: following discussion w/ tromey, if the the 2693663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng type doesn't have name, just make one up, and accept it. 2694663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng It might be referred to by other DIEs, so ignoring it 2695663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng doesn't seem like a safe option. */ 2696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (typeE.Te.TyStOrUn.name == NULL) 2697663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng typeE.Te.TyStOrUn.name 2698663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng = ML_(dinfo_strdup)( "di.readdwarf3.ptD.struct_type.3", 2699663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "<anon_struct_type>" ); 2700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyStOrUn.complete = False; 2701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* JRS 2009 Aug 10: <possible kludge>? */ 2702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Push this tyent on the stack, even though it's incomplete. 2703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown It appears that gcc-4.4 on Fedora 11 will sometimes create 2704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_TAG_member entries for it, and so we need to have a 2705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown plausible parent present in order for that to work. See 2706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown #200029 comments 8 and 9. */ 2707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typestack_push( cc, parser, td3, &typeE, level ); 2708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* </possible kludge> */ 2709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto acquire_Type; 2710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if ((!is_decl) /* && (!is_spec) */) { 2712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* this is the common, ordinary case */ 2713eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov /* The name can be present, or not */ 2714eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov if (!have_szB) { 2715eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov /* We must know the size. 2716eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov But in Ada, record with discriminants might have no size. 2717eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov But in C, VLA in the middle of a struct (gcc extension) 2718eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov might have no size. 2719eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov Instead, some GNAT dwarf extensions and/or dwarf entries 2720eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov allow to calculate the struct size at runtime. 2721eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov We cannot do that (yet?) so, the temporary kludge is to use 2722eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov a small size. */ 2723eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov typeE.Te.TyStOrUn.szB = 1; 2724eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov } 2725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* On't stack! */ 2726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typestack_push( cc, parser, td3, &typeE, level ); 2727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto acquire_Type; 2728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 2730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* don't know how to handle any other variants just now */ 2731eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov goto_bad_DIE; 2732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dtag == DW_TAG_member) { 2736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Acquire member entries for both DW_TAG_structure_type and 2737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_TAG_union_type. They differ minorly, in that struct 2738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown members must have a DW_AT_data_member_location expression 2739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown whereas union members must not. */ 2740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool parent_is_struct; 2741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)( &fieldE, 0, sizeof(fieldE) ); 2742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fieldE.cuOff = posn; 2743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fieldE.tag = Te_Field; 2744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fieldE.Te.Field.typeR = D3_INVALID_CUOFF; 2745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 2746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT attr = (DW_AT) get_ULEB128( c_abbv ); 2747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_FORM form = (DW_FORM)get_ULEB128( c_abbv ); 2748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (attr == 0 && form == 0) break; 2749436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); 2750436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_name && cts.szB < 0) { 2751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fieldE.Te.Field.name 2752436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = ML_(cur_read_strdup)( cts.u.cur, 2753436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "di.readdwarf3.ptD.member.1" ); 2754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2755436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_type && cts.szB > 0) { 2756436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fieldE.Te.Field.typeR 2757436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = cook_die_using_form( cc, (UWord)cts.u.val, form ); 2758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* There are 2 different cases for DW_AT_data_member_location. 2760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown If it is a constant class attribute, it contains byte offset 2761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown from the beginning of the containing entity. 2762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Otherwise it is a location expression. */ 2763436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_data_member_location && cts.szB > 0) { 2764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fieldE.Te.Field.nLoc = -1; 2765436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fieldE.Te.Field.pos.offset = cts.u.val; 2766436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 2767436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_data_member_location && cts.szB <= 0) { 2768436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov fieldE.Te.Field.nLoc = (UWord)(-cts.szB); 2769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fieldE.Te.Field.pos.loc 2770436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = ML_(cur_read_memdup)( cts.u.cur, 2771436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov (SizeT)fieldE.Te.Field.nLoc, 2772436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "di.readdwarf3.ptD.member.2" ); 2773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Do we have a plausible parent? */ 2776eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov if (typestack_is_empty(parser)) goto_bad_DIE; 2777ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp])); 2778ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->qparentE[parser->sp].cuOff != D3_INVALID_CUOFF); 2779eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov if (level != parser->qlevel[parser->sp]+1) goto_bad_DIE; 2780eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov if (parser->qparentE[parser->sp].tag != Te_TyStOrUn) goto_bad_DIE; 2781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Do we have something that looks sane? If this a member of a 2782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct, we must have a location expression; but if a member 2783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of a union that is irrelevant (D3 spec sec 5.6.6). We ought 2784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to reject in the latter case, but some compilers have been 2785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown observed to emit constant-zero expressions. So just ignore 2786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown them. */ 2787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parent_is_struct 2788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = parser->qparentE[parser->sp].Te.TyStOrUn.isStruct; 2789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!fieldE.Te.Field.name) 2790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fieldE.Te.Field.name 2791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = ML_(dinfo_strdup)( "di.readdwarf3.ptD.member.3", 2792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "<anon_field>" ); 2793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(fieldE.Te.Field.name); 2794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (fieldE.Te.Field.typeR == D3_INVALID_CUOFF) 2795eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov goto_bad_DIE; 2796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (fieldE.Te.Field.nLoc) { 2797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!parent_is_struct) { 2798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If this is a union type, pretend we haven't seen the data 2799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown member location expression, as it is by definition 2800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown redundant (it must be zero). */ 2801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (fieldE.Te.Field.nLoc > 0) 2802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(dinfo_free)(fieldE.Te.Field.pos.loc); 2803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fieldE.Te.Field.pos.loc = NULL; 2804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fieldE.Te.Field.nLoc = 0; 2805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Record this child in the parent */ 2807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fieldE.Te.Field.isStruct = parent_is_struct; 2808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->qparentE[parser->sp].Te.TyStOrUn.fieldRs); 2809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToXA)( parser->qparentE[parser->sp].Te.TyStOrUn.fieldRs, 2810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &posn ); 2811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* And record the child itself */ 2812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto acquire_Field; 2813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 2814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Member with no location - this can happen with static 2815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const members in C++ code which are compile time constants 2816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that do no exist in the class. They're not of any interest 2817ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to us so we ignore them. */ 2818663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ML_(TyEnt__make_EMPTY)(&fieldE); 2819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dtag == DW_TAG_array_type) { 2823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(&typeE, 0, sizeof(typeE)); 2824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.cuOff = posn; 2825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.tag = Te_TyArray; 2826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyArray.typeR = D3_INVALID_CUOFF; 2827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyArray.boundRs 2828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ptD.array_type.1", 2829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(dinfo_free), 2830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(UWord) ); 2831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 2832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT attr = (DW_AT) get_ULEB128( c_abbv ); 2833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_FORM form = (DW_FORM)get_ULEB128( c_abbv ); 2834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (attr == 0 && form == 0) break; 2835436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); 2836436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_type && cts.szB > 0) { 2837436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov typeE.Te.TyArray.typeR 2838436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = cook_die_using_form( cc, (UWord)cts.u.val, form ); 2839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (typeE.Te.TyArray.typeR == D3_INVALID_CUOFF) 2842eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov goto_bad_DIE; 2843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* On't stack! */ 2844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typestack_push( cc, parser, td3, &typeE, level ); 2845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto acquire_Type; 2846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2848f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* this is a subrange type defining the bounds of an array. */ 2849f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (dtag == DW_TAG_subrange_type 2850f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root && subrange_type_denotes_array_bounds(parser, dtag)) { 2851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool have_lower = False; 2852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool have_upper = False; 2853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool have_count = False; 2854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Long lower = 0; 2855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Long upper = 0; 2856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (parser->language) { 2858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'C': have_lower = True; lower = 0; break; 2859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 'F': have_lower = True; lower = 1; break; 2860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case '?': have_lower = False; break; 2861f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root case 'A': have_lower = False; break; 2862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: vg_assert(0); /* assured us by handling of 2863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_TAG_compile_unit in this fn */ 2864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)( &boundE, 0, sizeof(boundE) ); 2867ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.cuOff = D3_INVALID_CUOFF; 2868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.tag = Te_Bound; 2869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 2870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT attr = (DW_AT) get_ULEB128( c_abbv ); 2871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_FORM form = (DW_FORM)get_ULEB128( c_abbv ); 2872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (attr == 0 && form == 0) break; 2873436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); 2874436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_lower_bound && cts.szB > 0) { 2875436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov lower = (Long)cts.u.val; 2876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown have_lower = True; 2877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2878436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_upper_bound && cts.szB > 0) { 2879436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov upper = (Long)cts.u.val; 2880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown have_upper = True; 2881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2882436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_count && cts.szB > 0) { 2883436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /*count = (Long)cts.u.val;*/ 2884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown have_count = True; 2885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* FIXME: potentially skip the rest if no parent present, since 2888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown it could be the case that this subrange type is free-standing 2889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (not being used to describe the bounds of a containing array 2890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown type) */ 2891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Do we have a plausible parent? */ 2892eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov if (typestack_is_empty(parser)) goto_bad_DIE; 2893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ML_(TyEnt__is_type)(&parser->qparentE[parser->sp])); 2894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->qparentE[parser->sp].cuOff != D3_INVALID_CUOFF); 2895eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov if (level != parser->qlevel[parser->sp]+1) goto_bad_DIE; 2896eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov if (parser->qparentE[parser->sp].tag != Te_TyArray) goto_bad_DIE; 2897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Figure out if we have a definite range or not */ 2899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (have_lower && have_upper && (!have_count)) { 2900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.Te.Bound.knownL = True; 2901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.Te.Bound.knownU = True; 2902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.Te.Bound.boundL = lower; 2903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.Te.Bound.boundU = upper; 2904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if (have_lower && (!have_upper) && (!have_count)) { 2906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.Te.Bound.knownL = True; 2907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.Te.Bound.knownU = False; 2908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.Te.Bound.boundL = lower; 2909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.Te.Bound.boundU = 0; 2910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if ((!have_lower) && have_upper && (!have_count)) { 2912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.Te.Bound.knownL = False; 2913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.Te.Bound.knownU = True; 2914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.Te.Bound.boundL = 0; 2915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.Te.Bound.boundU = upper; 2916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else if ((!have_lower) && (!have_upper) && (!have_count)) { 2918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.Te.Bound.knownL = False; 2919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.Te.Bound.knownU = False; 2920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.Te.Bound.boundL = 0; 2921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.Te.Bound.boundU = 0; 2922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 2923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* FIXME: handle more cases */ 2924eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov goto_bad_DIE; 2925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Record this bound in the parent */ 2928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.cuOff = posn; 2929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(parser->qparentE[parser->sp].Te.TyArray.boundRs); 2930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToXA)( parser->qparentE[parser->sp].Te.TyArray.boundRs, 2931663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng &boundE.cuOff ); 2932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* And record the child itself */ 2933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto acquire_Bound; 2934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2936f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* typedef or subrange_type other than array bounds. */ 2937f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root if (dtag == DW_TAG_typedef 2938f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root || (dtag == DW_TAG_subrange_type 2939f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root && !subrange_type_denotes_array_bounds(parser, dtag))) { 2940f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* subrange_type other than array bound is only for Ada. */ 2941f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root vg_assert (dtag == DW_TAG_typedef || parser->language == 'A'); 2942f673d1bf8bfb172f0eccbe4d3a908b3c65b55b33Kenny Root /* We can pick up a new typedef/subrange_type any time. */ 2943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(&typeE, 0, sizeof(typeE)); 2944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.cuOff = D3_INVALID_CUOFF; 2945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.tag = Te_TyTyDef; 2946ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyTyDef.name = NULL; 2947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyTyDef.typeR = D3_INVALID_CUOFF; 2948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 2949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT attr = (DW_AT) get_ULEB128( c_abbv ); 2950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_FORM form = (DW_FORM)get_ULEB128( c_abbv ); 2951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (attr == 0 && form == 0) break; 2952436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); 2953436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_name && cts.szB < 0) { 2954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyTyDef.name 2955436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = ML_(cur_read_strdup)( cts.u.cur, 2956436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "di.readdwarf3.ptD.typedef.1" ); 2957ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2958436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_type && cts.szB > 0) { 2959436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov typeE.Te.TyTyDef.typeR 2960436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = cook_die_using_form( cc, (UWord)cts.u.val, form ); 2961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2963436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Do we have something that looks sane? 2964436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov gcc gnat Ada generates minimal typedef 2965436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov such as the below 2966436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov <6><91cc>: DW_TAG_typedef 2967436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DW_AT_abstract_ori: <9066> 2968436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov g++ for OMP can generate artificial functions that have 2969436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov parameters that refer to pointers to unnamed typedefs. 2970436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov See https://bugs.kde.org/show_bug.cgi?id=273475 2971436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov So we cannot require a name for a DW_TAG_typedef. 2972436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov */ 2973436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov goto acquire_Type; 2974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dtag == DW_TAG_subroutine_type) { 2977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* function type? just record that one fact and ask no 2978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown further questions. */ 2979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(&typeE, 0, sizeof(typeE)); 2980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.cuOff = D3_INVALID_CUOFF; 2981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.tag = Te_TyFn; 2982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto acquire_Type; 2983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 2984ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (dtag == DW_TAG_volatile_type || dtag == DW_TAG_const_type) { 2986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int have_ty = 0; 2987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(&typeE, 0, sizeof(typeE)); 2988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.cuOff = D3_INVALID_CUOFF; 2989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.tag = Te_TyQual; 2990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyQual.qual 2991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = dtag == DW_TAG_volatile_type ? 'V' : 'C'; 2992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* target type defaults to 'void' */ 2993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.Te.TyQual.typeR = D3_FAKEVOID_CUOFF; 2994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 2995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT attr = (DW_AT) get_ULEB128( c_abbv ); 2996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_FORM form = (DW_FORM)get_ULEB128( c_abbv ); 2997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (attr == 0 && form == 0) break; 2998436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov get_Form_contents( &cts, cc, c_die, False/*td3*/, form ); 2999436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (attr == DW_AT_type && cts.szB > 0) { 3000436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov typeE.Te.TyQual.typeR 3001436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = cook_die_using_form( cc, (UWord)cts.u.val, form ); 3002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown have_ty++; 3003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* gcc sometimes generates DW_TAG_const/volatile_type without 3006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT_type and GDB appears to interpret the type as 'const 3007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void' (resp. 'volatile void'). So just allow it .. */ 3008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (have_ty == 1 || have_ty == 0) 3009ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown goto acquire_Type; 3010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 3011eb0bae136f4eeaaf29761dddb148b118fb824632Dmitriy Ivanov goto_bad_DIE; 3012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3014663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* 3015663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * Treat DW_TAG_unspecified_type as type void. An example of DW_TAG_unspecified_type: 3016663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * 3017663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * $ readelf --debug-dump /usr/lib/debug/usr/lib/libstdc++.so.6.0.16.debug 3018663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * <1><10d4>: Abbrev Number: 53 (DW_TAG_unspecified_type) 3019663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng * <10d5> DW_AT_name : (indirect string, offset: 0xdb7): decltype(nullptr) 3020663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng */ 3021663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (dtag == DW_TAG_unspecified_type) { 3022663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(memset)(&typeE, 0, sizeof(typeE)); 3023663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng typeE.cuOff = D3_INVALID_CUOFF; 3024663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng typeE.tag = Te_TyQual; 3025663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng typeE.Te.TyQual.typeR = D3_FAKEVOID_CUOFF; 3026663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng goto acquire_Type; 3027663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3028663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* else ignore this DIE */ 3030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 3031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ 3032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown acquire_Type: 3034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) VG_(printf)("YYYY Acquire Type\n"); 3035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ML_(TyEnt__is_type)( &typeE )); 3036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(typeE.cuOff == D3_INVALID_CUOFF || typeE.cuOff == posn); 3037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typeE.cuOff = posn; 3038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToXA)( tyents, &typeE ); 3039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 3040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ 3041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown acquire_Atom: 3043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) VG_(printf)("YYYY Acquire Atom\n"); 3044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(atomE.tag == Te_Atom); 3045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(atomE.cuOff == D3_INVALID_CUOFF || atomE.cuOff == posn); 3046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atomE.cuOff = posn; 3047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToXA)( tyents, &atomE ); 3048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 3049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ 3050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown acquire_Field: 3052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* For union members, Expr should be absent */ 3053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) VG_(printf)("YYYY Acquire Field\n"); 3054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(fieldE.tag == Te_Field); 3055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(fieldE.Te.Field.nLoc <= 0 || fieldE.Te.Field.pos.loc != NULL); 3056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(fieldE.Te.Field.nLoc != 0 || fieldE.Te.Field.pos.loc == NULL); 3057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (fieldE.Te.Field.isStruct) { 3058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(fieldE.Te.Field.nLoc != 0); 3059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 3060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(fieldE.Te.Field.nLoc == 0); 3061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(fieldE.cuOff == D3_INVALID_CUOFF || fieldE.cuOff == posn); 3063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fieldE.cuOff = posn; 3064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToXA)( tyents, &fieldE ); 3065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 3066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ 3067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown acquire_Bound: 3069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) VG_(printf)("YYYY Acquire Bound\n"); 3070ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(boundE.tag == Te_Bound); 3071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(boundE.cuOff == D3_INVALID_CUOFF || boundE.cuOff == posn); 3072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown boundE.cuOff = posn; 3073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToXA)( tyents, &boundE ); 3074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return; 3075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ 3076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bad_DIE: 3078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set_position_of_Cursor( c_die, saved_die_c_offset ); 3079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set_position_of_Cursor( c_abbv, saved_abbv_c_offset ); 3080663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng posn = uncook_die( cc, posn, &debug_types_flag, &alt_flag ); 3081663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(printf)(" <%d><%lx>: %s", level, posn, ML_(pp_DW_TAG)( dtag ) ); 3082663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (debug_types_flag) { 3083663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(printf)(" (in .debug_types)"); 3084663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else if (alt_flag) { 3085663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(printf)(" (in alternate .debug_info)"); 3086663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3087663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(printf)("\n"); 3088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 3089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_AT attr = (DW_AT) get_ULEB128( c_abbv ); 3090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DW_FORM form = (DW_FORM)get_ULEB128( c_abbv ); 3091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (attr == 0 && form == 0) break; 3092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)(" %18s: ", ML_(pp_DW_AT)(attr)); 3093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Get the form contents, so as to print them */ 3094436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov get_Form_contents( &cts, cc, c_die, True, form ); 3095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("\t\n"); 3096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("\n"); 3098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf("parse_type_DIE: confused by the above DIE"); 3099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ 3100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 3104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 3105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Compression of type DIE information ---*/ 3106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 3107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 3108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UWord chase_cuOff ( Bool* changed, 3110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* /* of TyEnt */ ents, 3111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEntIndexCache* ents_cache, 3112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord cuOff ) 3113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEnt* ent; 3115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache, cuOff ); 3116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!ent) { 3118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("chase_cuOff: no entry for 0x%05lx\n", cuOff); 3119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *changed = False; 3120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return cuOff; 3121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ent->tag != Te_EMPTY); 3124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ent->tag != Te_INDIR) { 3125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *changed = False; 3126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return cuOff; 3127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 3128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ent->Te.INDIR.indR < cuOff); 3129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *changed = True; 3130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return ent->Te.INDIR.indR; 3131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 3135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid chase_cuOffs_in_XArray ( Bool* changed, 3136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* /* of TyEnt */ ents, 3137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEntIndexCache* ents_cache, 3138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/XArray* /* of UWord */ cuOffs ) 3139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool b2 = False; 3141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word i, n = VG_(sizeXA)( cuOffs ); 3142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n; i++) { 3143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool b = False; 3144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord* p = VG_(indexXA)( cuOffs, i ); 3145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *p = chase_cuOff( &b, ents, ents_cache, *p ); 3146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (b) 3147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown b2 = True; 3148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *changed = b2; 3150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool TyEnt__subst_R_fields ( XArray* /* of TyEnt */ ents, 3153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEntIndexCache* ents_cache, 3154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/TyEnt* te ) 3155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool b, changed = False; 3157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (te->tag) { 3158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Te_EMPTY: 3159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Te_INDIR: 3161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown te->Te.INDIR.indR 3162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = chase_cuOff( &b, ents, ents_cache, te->Te.INDIR.indR ); 3163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (b) changed = True; 3164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Te_UNKNOWN: 3166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Te_Atom: 3168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Te_Field: 3170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown te->Te.Field.typeR 3171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = chase_cuOff( &b, ents, ents_cache, te->Te.Field.typeR ); 3172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (b) changed = True; 3173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Te_Bound: 3175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Te_TyBase: 3177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Te_TyPtr: 3179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Te_TyRef: 3180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Te_TyPtrMbr: 3181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng case Te_TyRvalRef: 3182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown te->Te.TyPorR.typeR 3183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = chase_cuOff( &b, ents, ents_cache, te->Te.TyPorR.typeR ); 3184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (b) changed = True; 3185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Te_TyTyDef: 3187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown te->Te.TyTyDef.typeR 3188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = chase_cuOff( &b, ents, ents_cache, te->Te.TyTyDef.typeR ); 3189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (b) changed = True; 3190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Te_TyStOrUn: 3192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyStOrUn.fieldRs ); 3193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (b) changed = True; 3194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Te_TyEnum: 3196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyEnum.atomRs ); 3197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (b) changed = True; 3198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Te_TyArray: 3200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown te->Te.TyArray.typeR 3201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = chase_cuOff( &b, ents, ents_cache, te->Te.TyArray.typeR ); 3202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (b) changed = True; 3203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown chase_cuOffs_in_XArray( &b, ents, ents_cache, te->Te.TyArray.boundRs ); 3204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (b) changed = True; 3205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Te_TyFn: 3207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Te_TyQual: 3209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown te->Te.TyQual.typeR 3210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = chase_cuOff( &b, ents, ents_cache, te->Te.TyQual.typeR ); 3211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (b) changed = True; 3212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case Te_TyVoid: 3214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown default: 3216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(pp_TyEnt)(te); 3217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(0); 3218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return changed; 3220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Make a pass over 'ents'. For each tyent, inspect the target of any 3223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 'R' or 'Rs' fields (those which refer to other tyents), and replace 3224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown any which point to INDIR nodes with the target of the indirection 3225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (which should not itself be an indirection). In summary, this 3226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown routine shorts out all references to indirection nodes. */ 3227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 3228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownWord dedup_types_substitution_pass ( /*MOD*/XArray* /* of TyEnt */ ents, 3229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEntIndexCache* ents_cache ) 3230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word i, n, nChanged = 0; 3232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool b; 3233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n = VG_(sizeXA)( ents ); 3234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n; i++) { 3235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEnt* ent = VG_(indexXA)( ents, i ); 3236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ent->tag != Te_EMPTY); 3237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* We have to substitute everything, even indirections, so as to 3238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ensure that chains of indirections don't build up. */ 3239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown b = TyEnt__subst_R_fields( ents, ents_cache, ent ); 3240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (b) 3241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown nChanged++; 3242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return nChanged; 3245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Make a pass over 'ents', building a dictionary of TyEnts as we go. 3249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Look up each new tyent in the dictionary in turn. If it is already 3250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in the dictionary, replace this tyent with an indirection to the 3251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown existing one, and delete any malloc'd stuff hanging off this one. 3252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown In summary, this routine commons up all tyents that are identical 3253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown as defined by TyEnt__cmp_by_all_except_cuOff. */ 3254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 3255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownWord dedup_types_commoning_pass ( /*MOD*/XArray* /* of TyEnt */ ents ) 3256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word n, i, nDeleted; 3258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WordFM* dict; /* TyEnt* -> void */ 3259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEnt* ent; 3260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord keyW, valW; 3261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dict = VG_(newFM)( 3263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(dinfo_zalloc), "di.readdwarf3.dtcp.1", 3264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(dinfo_free), 3265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (Word(*)(UWord,UWord)) ML_(TyEnt__cmp_by_all_except_cuOff) 3266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 3267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown nDeleted = 0; 3269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n = VG_(sizeXA)( ents ); 3270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n; i++) { 3271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ent = VG_(indexXA)( ents, i ); 3272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ent->tag != Te_EMPTY); 3273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Ignore indirections, although check that they are 3275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown not forming a cycle. */ 3276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ent->tag == Te_INDIR) { 3277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ent->Te.INDIR.indR < ent->cuOff); 3278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 3279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown keyW = valW = 0; 3282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(lookupFM)( dict, &keyW, &valW, (UWord)ent )) { 3283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* it's already in the dictionary. */ 3284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEnt* old = (TyEnt*)keyW; 3285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(valW == 0); 3286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(old != ent); 3287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(old->tag != Te_INDIR); 3288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* since we are traversing the array in increasing order of 3289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cuOff: */ 3290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(old->cuOff < ent->cuOff); 3291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* So anyway, dump this entry and replace it with an 3292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown indirection to the one in the dictionary. Note that the 3293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown assertion above guarantees that we cannot create cycles of 3294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown indirections, since we are always creating an indirection 3295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to a tyent with a cuOff lower than this one. */ 3296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(TyEnt__make_EMPTY)( ent ); 3297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ent->tag = Te_INDIR; 3298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ent->Te.INDIR.indR = old->cuOff; 3299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown nDeleted++; 3300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 3301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* not in dictionary; add it and keep going. */ 3302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToFM)( dict, (UWord)ent, 0 ); 3303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(deleteFM)( dict, NULL, NULL ); 3307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return nDeleted; 3309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 3313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid dedup_types ( Bool td3, 3314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/XArray* /* of TyEnt */ ents, 3315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEntIndexCache* ents_cache ) 3316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word m, n, i, nDel, nSubst, nThresh; 3318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) td3 = True; 3319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n = VG_(sizeXA)( ents ); 3321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If a commoning pass and a substitution pass both make fewer than 3323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown this many changes, just stop. It's pointless to burn up CPU 3324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown time trying to compress the last 1% or so out of the array. */ 3325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown nThresh = n / 200; 3326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* First we must sort .ents by its .cuOff fields, so we 3328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown can index into it. */ 3329436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(setCmpFnXA)( ents, (XACmpFn_t) ML_(TyEnt__cmp_by_cuOff_only) ); 3330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sortXA)( ents ); 3331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Now repeatedly do commoning and substitution passes over 3333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the array, until there are no more changes. */ 3334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { 3335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown nDel = dedup_types_commoning_pass ( ents ); 3336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown nSubst = dedup_types_substitution_pass ( ents, ents_cache ); 3337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(nDel >= 0 && nSubst >= 0); 3338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" %ld deletions, %ld substitutions\n", nDel, nSubst); 3339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (nDel > nThresh || nSubst > nThresh); 3340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Sanity check: all INDIR nodes should point at a non-INDIR thing. 3342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown In fact this should be true at the end of every loop iteration 3343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown above (a commoning pass followed by a substitution pass), but 3344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown checking it on every iteration is excessively expensive. Note, 3345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown this loop also computes 'm' for the stats printing below it. */ 3346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown m = 0; 3347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n = VG_(sizeXA)( ents ); 3348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n; i++) { 3349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEnt *ent, *ind; 3350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ent = VG_(indexXA)( ents, i ); 3351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ent->tag != Te_INDIR) continue; 3352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown m++; 3353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ind = ML_(TyEnts__index_by_cuOff)( ents, ents_cache, 3354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ent->Te.INDIR.indR ); 3355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ind); 3356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ind->tag != Te_INDIR); 3357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("Overall: %ld before, %ld after\n", n, n-m); 3360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 3364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 3365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Resolution of references to type DIEs ---*/ 3366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 3367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 3368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Make a pass through the (temporary) variables array. Examine the 3370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown type of each variable, check is it found, and chase any Te_INDIRs. 3371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Postcondition is: each variable has a typeR field that refers to a 3372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown valid type in tyents, or a Te_UNKNOWN, and is certainly guaranteed 3373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown not to refer to a Te_INDIR. (This is so that we can throw all the 3374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Te_INDIRs away later). */ 3375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline)) 3377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void resolve_variable_types ( 3378436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov void (*barf)( const HChar* ) __attribute__((noreturn)), 3379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*R-O*/XArray* /* of TyEnt */ ents, 3380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/TyEntIndexCache* ents_cache, 3381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/XArray* /* of TempVar* */ vars 3382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ) 3383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word i, n; 3385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n = VG_(sizeXA)( vars ); 3386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n; i++) { 3387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TempVar* var = *(TempVar**)VG_(indexXA)( vars, i ); 3388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This is the stated type of the variable. But it might be 3389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown an indirection, so be careful. */ 3390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEnt* ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache, 3391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown var->typeR ); 3392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ent && ent->tag == Te_INDIR) { 3393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ent = ML_(TyEnts__index_by_cuOff)( ents, ents_cache, 3394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ent->Te.INDIR.indR ); 3395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ent); 3396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ent->tag != Te_INDIR); 3397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Deal first with "normal" cases */ 3400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ent && ML_(TyEnt__is_type)(ent)) { 3401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown var->typeR = ent->cuOff; 3402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 3403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If there's no ent, it probably we did not manage to read a 3406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown type at the cuOffset which is stated as being this variable's 3407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown type. Maybe a deficiency in parse_type_DIE. Complain. */ 3408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ent == NULL) { 3409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("\n: Invalid cuOff = 0x%05lx\n", var->typeR ); 3410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown barf("resolve_variable_types: " 3411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "cuOff does not refer to a known type"); 3412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ent); 3414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If ent has any other tag, something bad happened, along the 3415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown lines of var->typeR not referring to a type at all. */ 3416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ent->tag == Te_UNKNOWN); 3417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Just accept it; the type will be useless, but at least keep 3418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown going. */ 3419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown var->typeR = ent->cuOff; 3420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 3425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 3426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Parsing of Compilation Units ---*/ 3427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 3428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 3429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3430436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic Int cmp_TempVar_by_dioff ( const void* v1, const void* v2 ) { 3431436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const TempVar* t1 = *(const TempVar *const *)v1; 3432436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const TempVar* t2 = *(const TempVar *const *)v2; 3433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (t1->dioff < t2->dioff) return -1; 3434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (t1->dioff > t2->dioff) return 1; 3435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 3436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void read_DIE ( 3439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/WordFM* /* of (XArray* of AddrRange, void) */ rangestree, 3440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/XArray* /* of TyEnt */ tyents, 3441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/XArray* /* of TempVar* */ tempvars, 3442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/XArray* /* of GExpr* */ gexprs, 3443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/D3TypeParser* typarser, 3444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/D3VarParser* varparser, 3445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Cursor* c, Bool td3, CUConst* cc, Int level 3446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown) 3447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Cursor abbv; 3449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong atag, abbv_code; 3450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord posn; 3451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt has_children; 3452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord start_die_c_offset, start_abbv_c_offset; 3453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord after_die_c_offset, after_abbv_c_offset; 3454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- Deal with this DIE --- */ 3456663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng posn = cook_die( cc, get_position_of_Cursor( c ) ); 3457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown abbv_code = get_ULEB128( c ); 3458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set_abbv_Cursor( &abbv, td3, cc, abbv_code ); 3459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atag = get_ULEB128( &abbv ); 3460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("\n"); 3461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" <%d><%lx>: Abbrev Number: %llu (%s)\n", 3462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown level, posn, abbv_code, ML_(pp_DW_TAG)( atag ) ); 3463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (atag == 0) 3465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf("read_DIE: invalid zero tag on DIE"); 3466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown has_children = get_UChar( &abbv ); 3468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (has_children != DW_children_no && has_children != DW_children_yes) 3469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc->barf("read_DIE: invalid has_children value"); 3470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* We're set up to look at the fields of this DIE. Hand it off to 3472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown any parser(s) that want to see it. Since they will in general 3473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown advance both the DIE and abbrev cursors, remember their current 3474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown settings so that we can then back up and do one final pass over 3475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the DIE, to print out its contents. */ 3476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown start_die_c_offset = get_position_of_Cursor( c ); 3478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown start_abbv_c_offset = get_position_of_Cursor( &abbv ); 3479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 3481436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov FormContents cts; 3482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong at_name = get_ULEB128( &abbv ); 3483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong at_form = get_ULEB128( &abbv ); 3484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (at_name == 0 && at_form == 0) break; 3485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" %18s: ", ML_(pp_DW_AT)(at_name)); 3486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Get the form contents, but ignore them; the only purpose is 3487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to print them, if td3 is True */ 3488436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov get_Form_contents( &cts, cc, c, td3, (DW_FORM)at_form ); 3489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("\t"); 3490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("\n"); 3491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown after_die_c_offset = get_position_of_Cursor( c ); 3494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown after_abbv_c_offset = get_position_of_Cursor( &abbv ); 3495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set_position_of_Cursor( c, start_die_c_offset ); 3497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set_position_of_Cursor( &abbv, start_abbv_c_offset ); 3498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parse_type_DIE( tyents, 3500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typarser, 3501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (DW_TAG)atag, 3502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown posn, 3503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown level, 3504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c, /* DIE cursor */ 3505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &abbv, /* abbrev cursor */ 3506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc, 3507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown td3 ); 3508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set_position_of_Cursor( c, start_die_c_offset ); 3510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set_position_of_Cursor( &abbv, start_abbv_c_offset ); 3511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parse_var_DIE( rangestree, 3513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tempvars, 3514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gexprs, 3515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varparser, 3516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (DW_TAG)atag, 3517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown posn, 3518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown level, 3519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c, /* DIE cursor */ 3520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &abbv, /* abbrev cursor */ 3521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cc, 3522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown td3 ); 3523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set_position_of_Cursor( c, after_die_c_offset ); 3525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown set_position_of_Cursor( &abbv, after_abbv_c_offset ); 3526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* --- Now recurse into its children, if any --- */ 3528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (has_children == DW_children_yes) { 3529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) TRACE_D3("BEGIN children of level %d\n", level); 3530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 3531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atag = peek_ULEB128( c ); 3532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (atag == 0) break; 3533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown read_DIE( rangestree, tyents, tempvars, gexprs, 3534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typarser, varparser, 3535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c, td3, cc, level+1 ); 3536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Now we need to eat the terminating zero */ 3538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown atag = get_ULEB128( c ); 3539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(atag == 0); 3540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0) TRACE_D3("END children of level %d\n", level); 3541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 3544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic 3547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid new_dwarf3_reader_wrk ( 3548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct _DebugInfo* di, 3549436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov __attribute__((noreturn)) void (*barf)( const HChar* ), 3550436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_info, DiSlice escn_debug_types, 3551436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_abbv, DiSlice escn_debug_line, 3552436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_str, DiSlice escn_debug_ranges, 3553436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_loc, DiSlice escn_debug_info_alt, 3554436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_abbv_alt, DiSlice escn_debug_line_alt, 3555436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_str_alt 3556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown) 3557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 3558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* /* of TyEnt */ tyents; 3559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* /* of TyEnt */ tyents_to_keep; 3560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* /* of GExpr* */ gexprs; 3561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* /* of TempVar* */ tempvars; 3562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WordFM* /* of (XArray* of AddrRange, void) */ rangestree; 3563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEntIndexCache* tyents_cache = NULL; 3564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEntIndexCache* tyents_to_keep_cache = NULL; 3565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TempVar *varp, *varp2; 3566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown GExpr* gexpr; 3567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Cursor abbv; /* for showing .debug_abbrev */ 3568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Cursor info; /* primary cursor for parsing .debug_info */ 3569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Cursor ranges; /* for showing .debug_ranges */ 3570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown D3TypeParser typarser; 3571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown D3VarParser varparser; 3572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr dr_base; 3573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord dr_offset; 3574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word i, j, n; 3575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool td3 = di->trace_symtab; 3576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown XArray* /* of TempVar* */ dioff_lookup_tab; 3577663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Int pass; 3578663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VgHashTable signature_types; 3579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0 3580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This doesn't work properly because it assumes all entries are 3581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown packed end to end, with no holes. But that doesn't always 3582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown appear to be the case, so it loses sync. And the D3 spec 3583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown doesn't appear to require a no-hole situation either. */ 3584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Display .debug_loc */ 3585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr dl_base; 3586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord dl_offset; 3587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Cursor loc; /* for showing .debug_loc */ 3588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_SYMTAB("\n"); 3589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_SYMTAB("\n------ The contents of .debug_loc ------\n"); 3590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_SYMTAB(" Offset Begin End Expression\n"); 3591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown init_Cursor( &loc, debug_loc_img, 3592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown debug_loc_sz, 0, barf, 3593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "Overrun whilst reading .debug_loc section(1)" ); 3594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dl_base = 0; 3595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dl_offset = 0; 3596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 3597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord w1, w2; 3598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord len; 3599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_at_end_Cursor( &loc )) 3600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 3601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Read a (host-)word pair. This is something of a hack since 3603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the word size to read is really dictated by the ELF file; 3604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown however, we assume we're reading a file with the same 3605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown word-sizeness as the host. Reasonably enough. */ 3606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown w1 = get_UWord( &loc ); 3607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown w2 = get_UWord( &loc ); 3608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (w1 == 0 && w2 == 0) { 3610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* end of list. reset 'base' */ 3611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" %08lx <End of list>\n", dl_offset); 3612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dl_base = 0; 3613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dl_offset = get_position_of_Cursor( &loc ); 3614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 3615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (w1 == -1UL) { 3618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* new value for 'base' */ 3619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" %08lx %16lx %08lx (base address)\n", 3620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dl_offset, w1, w2); 3621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dl_base = w2; 3622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 3623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* else a location expression follows */ 3626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" %08lx %08lx %08lx ", 3627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dl_offset, w1 + dl_base, w2 + dl_base); 3628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len = (UWord)get_UShort( &loc ); 3629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (len > 0) { 3630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar byte = get_UChar( &loc ); 3631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("%02x", (UInt)byte); 3632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len--; 3633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_SYMTAB("\n"); 3635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 3637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Display .debug_ranges */ 3639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_SYMTAB("\n"); 3640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_SYMTAB("\n------ The contents of .debug_ranges ------\n"); 3641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_SYMTAB(" Offset Begin End\n"); 3642436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (ML_(sli_is_valid)(escn_debug_ranges)) { 3643436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov init_Cursor( &ranges, escn_debug_ranges, 0, barf, 3644436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "Overrun whilst reading .debug_ranges section(1)" ); 3645436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov dr_base = 0; 3646436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov dr_offset = 0; 3647436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov while (True) { 3648436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UWord w1, w2; 3649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3650436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (is_at_end_Cursor( &ranges )) 3651436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 3652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3653436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Read a (host-)word pair. This is something of a hack since 3654436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov the word size to read is really dictated by the ELF file; 3655436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov however, we assume we're reading a file with the same 3656436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov word-sizeness as the host. Reasonably enough. */ 3657436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov w1 = get_UWord( &ranges ); 3658436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov w2 = get_UWord( &ranges ); 3659436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 3660436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (w1 == 0 && w2 == 0) { 3661436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* end of list. reset 'base' */ 3662436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3(" %08lx <End of list>\n", dr_offset); 3663436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov dr_base = 0; 3664436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov dr_offset = get_position_of_Cursor( &ranges ); 3665436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov continue; 3666436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3668436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (w1 == -1UL) { 3669436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* new value for 'base' */ 3670436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3(" %08lx %16lx %08lx (base address)\n", 3671436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov dr_offset, w1, w2); 3672436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov dr_base = w2; 3673436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov continue; 3674436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3676436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* else a range [w1+base, w2+base) is denoted */ 3677436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3(" %08lx %08lx %08lx\n", 3678436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov dr_offset, w1 + dr_base, w2 + dr_base); 3679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Display .debug_abbrev */ 3683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_SYMTAB("\n"); 3684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_SYMTAB("\n------ The contents of .debug_abbrev ------\n"); 3685436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (ML_(sli_is_valid)(escn_debug_abbv)) { 3686436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov init_Cursor( &abbv, escn_debug_abbv, 0, barf, 3687436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "Overrun whilst reading .debug_abbrev section" ); 3688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 3689436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (is_at_end_Cursor( &abbv )) 3690436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov break; 3691436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Read one abbreviation table */ 3692436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3(" Number TAG\n"); 3693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 3694436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong atag; 3695436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt has_children; 3696436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong acode = get_ULEB128( &abbv ); 3697436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (acode == 0) break; /* end of the table */ 3698436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov atag = get_ULEB128( &abbv ); 3699436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov has_children = get_UChar( &abbv ); 3700436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3(" %llu %s [%s]\n", 3701436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov acode, ML_(pp_DW_TAG)(atag), 3702436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ML_(pp_DW_children)(has_children)); 3703436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov while (True) { 3704436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong at_name = get_ULEB128( &abbv ); 3705436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong at_form = get_ULEB128( &abbv ); 3706436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (at_name == 0 && at_form == 0) break; 3707436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3(" %18s %s\n", 3708436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ML_(pp_DW_AT)(at_name), ML_(pp_DW_FORM)(at_form)); 3709436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_SYMTAB("\n"); 3714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* We'll park the harvested type information in here. Also create 3716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown a fake "void" entry with offset D3_FAKEVOID_CUOFF, so we always 3717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown have at least one type entry to refer to. D3_FAKEVOID_CUOFF is 3718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown huge and presumably will not occur in any valid DWARF3 file -- 3719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown it would need to have a .debug_info section 4GB long for that to 3720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown happen. These type entries end up in the DebugInfo. */ 3721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tyents = VG_(newXA)( ML_(dinfo_zalloc), 3722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "di.readdwarf3.ndrw.1 (TyEnt temp array)", 3723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(dinfo_free), sizeof(TyEnt) ); 3724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { TyEnt tyent; 3725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(&tyent, 0, sizeof(tyent)); 3726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tyent.tag = Te_TyVoid; 3727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tyent.cuOff = D3_FAKEVOID_CUOFF; 3728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tyent.Te.TyVoid.isFake = True; 3729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToXA)( tyents, &tyent ); 3730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { TyEnt tyent; 3732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(&tyent, 0, sizeof(tyent)); 3733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tyent.tag = Te_UNKNOWN; 3734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tyent.cuOff = D3_INVALID_CUOFF; 3735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToXA)( tyents, &tyent ); 3736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* This is a tree used to unique-ify the range lists that are 3739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown manufactured by parse_var_DIE. References to the keys in the 3740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tree wind up in .rngMany fields in TempVars. We'll need to 3741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown delete this tree, and the XArrays attached to it, at the end of 3742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown this function. */ 3743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rangestree = VG_(newFM)( ML_(dinfo_zalloc), 3744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "di.readdwarf3.ndrw.2 (rangestree)", 3745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(dinfo_free), 3746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (Word(*)(UWord,UWord))cmp__XArrays_of_AddrRange ); 3747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* List of variables we're accumulating. These don't end up in the 3749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DebugInfo; instead their contents are handed to ML_(addVar) and 3750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the list elements are then deleted. */ 3751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tempvars = VG_(newXA)( ML_(dinfo_zalloc), 3752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "di.readdwarf3.ndrw.3 (TempVar*s array)", 3753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(dinfo_free), 3754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(TempVar*) ); 3755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* List of GExprs we're accumulating. These wind up in the 3757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DebugInfo. */ 3758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gexprs = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.4", 3759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(dinfo_free), sizeof(GExpr*) ); 3760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* We need a D3TypeParser to keep track of partially constructed 3762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown types. It'll be discarded as soon as we've completed the CU, 3763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown since the resulting information is tipped in to 'tyents' as it 3764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown is generated. */ 3765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)( &typarser, 0, sizeof(typarser) ); 3766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typarser.sp = -1; 3767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typarser.language = '?'; 3768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < N_D3_TYPE_STACK; i++) { 3769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typarser.qparentE[i].tag = Te_EMPTY; 3770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown typarser.qparentE[i].cuOff = D3_INVALID_CUOFF; 3771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)( &varparser, 0, sizeof(varparser) ); 3774ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varparser.sp = -1; 3775ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3776663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng signature_types = VG_(HT_construct) ("signature_types"); 3777663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3778663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Do an initial pass to scan the .debug_types section, if any, and 3779663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng fill in the signatured types hash table. This lets us handle 3780663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng mapping from a type signature to a (cooked) DIE offset directly 3781663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng in get_Form_contents. */ 3782436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (ML_(sli_is_valid)(escn_debug_types)) { 3783436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov init_Cursor( &info, escn_debug_types, 0, barf, 3784663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "Overrun whilst reading .debug_types section" ); 3785436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3("\n------ Collecting signatures from " 3786436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ".debug_types section ------\n"); 3787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3788663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng while (True) { 3789663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UWord cu_start_offset, cu_offset_now; 3790663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng CUConst cc; 3791663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3792663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cu_start_offset = get_position_of_Cursor( &info ); 3793663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng TRACE_D3("\n"); 3794663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng TRACE_D3(" Compilation Unit @ offset 0x%lx:\n", cu_start_offset); 3795663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* parse_CU_header initialises the CU's set_abbv_Cursor cache 3796663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (saC_cache) */ 3797436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov parse_CU_Header( &cc, td3, &info, escn_debug_abbv, True, False ); 3798663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3799663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Needed by cook_die. */ 3800436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc.types_cuOff_bias = escn_debug_info.szB; 3801663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3802663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng record_signatured_type( signature_types, cc.type_signature, 3803663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cook_die( &cc, cc.type_offset )); 3804663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3805663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Until proven otherwise we assume we don't need the icc9 3806663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng workaround in this case; see the DIE-reading loop below 3807663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for details. */ 3808663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cu_offset_now = (cu_start_offset + cc.unit_length 3809663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng + (cc.is_dw64 ? 12 : 4)); 3810663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3811436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (cu_offset_now >= escn_debug_types.szB) 3812663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3813663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3814663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng set_position_of_Cursor ( &info, cu_offset_now ); 3815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3816663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3817663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3818663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Perform three DIE-reading passes. The first pass reads DIEs from 3819663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng alternate .debug_info (if any), the second pass reads DIEs from 3820663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng .debug_info, and the third pass reads DIEs from .debug_types. 3821663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Moving the body of this loop into a separate function would 3822663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng require a large number of arguments to be passed in, so it is 3823663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng kept inline instead. */ 3824663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (pass = 0; pass < 3; ++pass) { 3825436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong section_size; 3826663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3827663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (pass == 0) { 3828436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (!ML_(sli_is_valid)(escn_debug_info_alt)) 3829663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng continue; 3830663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Now loop over the Compilation Units listed in the alternate 3831663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng .debug_info section (see D3SPEC sec 7.5) paras 1 and 2. 3832663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Each compilation unit contains a Compilation Unit Header 3833663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng followed by precisely one DW_TAG_compile_unit or 3834663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DW_TAG_partial_unit DIE. */ 3835436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov init_Cursor( &info, escn_debug_info_alt, 0, barf, 3836663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "Overrun whilst reading alternate .debug_info section" ); 3837436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov section_size = escn_debug_info_alt.szB; 3838663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3839663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng TRACE_D3("\n------ Parsing alternate .debug_info section ------\n"); 3840663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else if (pass == 1) { 3841663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Now loop over the Compilation Units listed in the .debug_info 3842663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng section (see D3SPEC sec 7.5) paras 1 and 2. Each compilation 3843663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng unit contains a Compilation Unit Header followed by precisely 3844663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng one DW_TAG_compile_unit or DW_TAG_partial_unit DIE. */ 3845436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov init_Cursor( &info, escn_debug_info, 0, barf, 3846663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "Overrun whilst reading .debug_info section" ); 3847436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov section_size = escn_debug_info.szB; 3848663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3849663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng TRACE_D3("\n------ Parsing .debug_info section ------\n"); 3850663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 3851436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (!ML_(sli_is_valid)(escn_debug_types)) 3852663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng continue; 3853436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov init_Cursor( &info, escn_debug_types, 0, barf, 3854663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "Overrun whilst reading .debug_types section" ); 3855436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov section_size = escn_debug_types.szB; 3856663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3857663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng TRACE_D3("\n------ Parsing .debug_types section ------\n"); 3858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 3859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3860663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng while (True) { 3861436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ULong cu_start_offset, cu_offset_now; 3862663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng CUConst cc; 3863663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* It may be that the stated size of this CU is larger than the 3864663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng amount of stuff actually in it. icc9 seems to generate CUs 3865663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng thusly. We use these variables to figure out if this is 3866663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng indeed the case, and if so how many bytes we need to skip to 3867663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng get to the start of the next CU. Not skipping those bytes 3868663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng causes us to misidentify the start of the next CU, and it all 3869663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng goes badly wrong after that (not surprisingly). */ 3870663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng UWord cu_size_including_IniLen, cu_amount_used; 3871663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3872663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* It seems icc9 finishes the DIE info before debug_info_sz 3873663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng bytes have been used up. So be flexible, and declare the 3874663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng sequence complete if there is not enough remaining bytes to 3875663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng hold even the smallest conceivable CU header. (11 bytes I 3876663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng reckon). */ 3877663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* JRS 23Jan09: I suspect this is no longer necessary now that 3878663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng the code below contains a 'while (cu_amount_used < 3879663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cu_size_including_IniLen ...' style loop, which skips over 3880663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng any leftover bytes at the end of a CU in the case where the 3881663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng CU's stated size is larger than its actual size (as 3882663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng determined by reading all its DIEs). However, for prudence, 3883663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng I'll leave the following test in place. I can't see that a 3884663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng CU header can be smaller than 11 bytes, so I don't think 3885663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng there's any harm possible through the test -- it just adds 3886663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng robustness. */ 3887663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Word avail = get_remaining_length_Cursor( &info ); 3888663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (avail < 11) { 3889663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (avail > 0) 3890663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng TRACE_D3("new_dwarf3_reader_wrk: warning: " 3891663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "%ld unused bytes after end of DIEs\n", avail); 3892663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 3893663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3894663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3895663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Check the varparser's stack is in a sane state. */ 3896663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vg_assert(varparser.sp == -1); 3897663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < N_D3_VAR_STACK; i++) { 3898663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vg_assert(varparser.ranges[i] == NULL); 3899663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vg_assert(varparser.level[i] == 0); 3900663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3901663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (i = 0; i < N_D3_TYPE_STACK; i++) { 3902663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vg_assert(typarser.qparentE[i].cuOff == D3_INVALID_CUOFF); 3903663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vg_assert(typarser.qparentE[i].tag == Te_EMPTY); 3904663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vg_assert(typarser.qlevel[i] == 0); 3905663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 3906663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3907663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cu_start_offset = get_position_of_Cursor( &info ); 3908663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng TRACE_D3("\n"); 3909436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov TRACE_D3(" Compilation Unit @ offset 0x%llx:\n", cu_start_offset); 3910663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* parse_CU_header initialises the CU's set_abbv_Cursor cache 3911663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (saC_cache) */ 3912436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (pass == 0) { 3913436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov parse_CU_Header( &cc, td3, &info, escn_debug_abbv_alt, 3914663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng False, True ); 3915436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 3916436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov parse_CU_Header( &cc, td3, &info, escn_debug_abbv, 3917663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng pass == 2, False ); 3918436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 3919436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc.escn_debug_str = pass == 0 ? escn_debug_str_alt 3920436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov : escn_debug_str; 3921436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc.escn_debug_ranges = escn_debug_ranges; 3922436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc.escn_debug_loc = escn_debug_loc; 3923436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc.escn_debug_line = pass == 0 ? escn_debug_line_alt 3924436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov : escn_debug_line; 3925436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc.escn_debug_info = pass == 0 ? escn_debug_info_alt 3926436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov : escn_debug_info; 3927436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc.escn_debug_types = escn_debug_types; 3928436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc.escn_debug_info_alt = escn_debug_info_alt; 3929436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc.escn_debug_str_alt = escn_debug_str_alt; 3930436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc.types_cuOff_bias = escn_debug_info.szB; 3931436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc.alt_cuOff_bias = escn_debug_info.szB + escn_debug_types.szB; 3932436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov cc.cu_start_offset = cu_start_offset; 3933663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc.di = di; 3934663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* The CU's svma can be deduced by looking at the AT_low_pc 3935663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng value in the top level TAG_compile_unit, which is the topmost 3936663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng DIE. We'll leave it for the 'varparser' to acquire that info 3937663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng and fill it in -- since it is the only party to want to know 3938663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng it. */ 3939663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc.cu_svma_known = False; 3940663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc.cu_svma = 0; 3941663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3942663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc.signature_types = signature_types; 3943663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3944663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Create a fake outermost-level range covering the entire 3945663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng address range. So we always have *something* to catch all 3946663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng variable declarations. */ 3947663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng varstack_push( &cc, &varparser, td3, 3948663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng unitary_range_list(0UL, ~0UL), 3949663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng -1, False/*isFunc*/, NULL/*fbGX*/ ); 3950663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3951663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* And set up the file name table. When we come across the top 3952663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng level DIE for this CU (which is what the next call to 3953663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng read_DIE should process) we will copy all the file names out 3954663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng of the .debug_line img area and use this table to look up the 3955663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng copies when we later see filename numbers in DW_TAG_variables 3956663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng etc. */ 3957663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vg_assert(!varparser.filenameTable ); 3958663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng varparser.filenameTable 3959663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.5", 3960663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ML_(dinfo_free), 3961663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng sizeof(UChar*) ); 3962663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vg_assert(varparser.filenameTable); 3963663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3964663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Now read the one-and-only top-level DIE for this CU. */ 3965663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vg_assert(varparser.sp == 0); 3966663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng read_DIE( rangestree, 3967663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tyents, tempvars, gexprs, 3968663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng &typarser, &varparser, 3969663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng &info, td3, &cc, 0 ); 3970663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown cu_offset_now = get_position_of_Cursor( &info ); 3972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3973436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (0) VG_(printf)("Travelled: %llu size %llu\n", 3974663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cu_offset_now - cc.cu_start_offset, 3975663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc.unit_length + (cc.is_dw64 ? 12 : 4)); 3976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3977663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* How big the CU claims it is .. */ 3978663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cu_size_including_IniLen = cc.unit_length + (cc.is_dw64 ? 12 : 4); 3979663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* .. vs how big we have found it to be */ 3980663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cu_amount_used = cu_offset_now - cc.cu_start_offset; 3981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 3982436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (1) TRACE_D3("offset now %lld, d-i-size %lld\n", 3983663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cu_offset_now, section_size); 3984663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (cu_offset_now > section_size) 3985663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng barf("toplevel DIEs beyond end of CU"); 3986663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3987663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* If the CU is bigger than it claims to be, we've got a serious 3988663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng problem. */ 3989663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (cu_amount_used > cu_size_including_IniLen) 3990663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng barf("CU's actual size appears to be larger than it claims it is"); 3991663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 3992663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* If the CU is smaller than it claims to be, we need to skip some 3993663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng bytes. Loop updates cu_offset_new and cu_amount_used. */ 3994663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng while (cu_amount_used < cu_size_including_IniLen 3995663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng && get_remaining_length_Cursor( &info ) > 0) { 3996663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (0) VG_(printf)("SKIP\n"); 3997663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (void)get_UChar( &info ); 3998663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cu_offset_now = get_position_of_Cursor( &info ); 3999663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cu_amount_used = cu_offset_now - cc.cu_start_offset; 4000663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4002663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Preen to level -2. DIEs have level >= 0 so -2 cannot occur 4003663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng anywhere else at all. Our fake the-entire-address-space 4004663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng range is at level -1, so preening to -2 should completely 4005663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng empty the stack out. */ 4006663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng TRACE_D3("\n"); 4007663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng varstack_preen( &varparser, td3, -2 ); 4008663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* Similarly, empty the type stack out. */ 4009663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng typestack_preen( &typarser, td3, -2 ); 4010663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4011663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng TRACE_D3("set_abbv_Cursor cache: %lu queries, %lu misses\n", 4012663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng cc.saC_cache_queries, cc.saC_cache_misses); 4013663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4014663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vg_assert(varparser.filenameTable ); 4015663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(deleteXA)( varparser.filenameTable ); 4016663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng varparser.filenameTable = NULL; 4017663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4018663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (cu_offset_now == section_size) 4019663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 4020663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* else keep going */ 4021663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* From here on we're post-processing the stuff we got 4025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown out of the .debug_info section. */ 4026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (td3) { 4027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("\n"); 4028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(pp_TyEnts)(tyents, "Initial type entity (TyEnt) array"); 4029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("\n"); 4030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("------ Compressing type entries ------\n"); 4031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4033ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tyents_cache = ML_(dinfo_zalloc)( "di.readdwarf3.ndrw.6", 4034ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(TyEntIndexCache) ); 4035ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(TyEntIndexCache__invalidate)( tyents_cache ); 4036ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dedup_types( td3, tyents, tyents_cache ); 4037ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (td3) { 4038ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("\n"); 4039ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(pp_TyEnts)(tyents, "After type entity (TyEnt) compression"); 4040ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4041ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4042ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("\n"); 4043ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("------ Resolving the types of variables ------\n" ); 4044ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown resolve_variable_types( barf, tyents, tyents_cache, tempvars ); 4045ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4046ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Copy all the non-INDIR tyents into a new table. For large 4047ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown .so's, about 90% of the tyents will by now have been resolved to 4048ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown INDIRs, and we no longer need them, and so don't need to store 4049ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown them. */ 4050ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tyents_to_keep 4051ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = VG_(newXA)( ML_(dinfo_zalloc), 4052ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "di.readdwarf3.ndrw.7 (TyEnt to-keep array)", 4053ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(dinfo_free), sizeof(TyEnt) ); 4054ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n = VG_(sizeXA)( tyents ); 4055ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n; i++) { 4056ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEnt* ent = VG_(indexXA)( tyents, i ); 4057ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ent->tag != Te_INDIR) 4058ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToXA)( tyents_to_keep, ent ); 4059ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4060ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4061ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(deleteXA)( tyents ); 4062ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tyents = NULL; 4063ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(dinfo_free)( tyents_cache ); 4064ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tyents_cache = NULL; 4065ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4066ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Sort tyents_to_keep so we can lookup in it. A complete (if 4067ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown minor) waste of time, since tyents itself is sorted, but 4068ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown necessary since VG_(lookupXA) refuses to cooperate if we 4069ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown don't. */ 4070436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(setCmpFnXA)( tyents_to_keep, (XACmpFn_t) ML_(TyEnt__cmp_by_cuOff_only) ); 4071ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sortXA)( tyents_to_keep ); 4072ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4073ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Enable cacheing on tyents_to_keep */ 4074ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tyents_to_keep_cache 4075ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = ML_(dinfo_zalloc)( "di.readdwarf3.ndrw.8", 4076ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(TyEntIndexCache) ); 4077ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(TyEntIndexCache__invalidate)( tyents_to_keep_cache ); 4078ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4079ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* And record the tyents in the DebugInfo. We do this before 4080ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown starting to hand variables to ML_(addVar), since if ML_(addVar) 4081ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown wants to do debug printing (of the types of said vars) then it 4082ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown will need the tyents.*/ 4083ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(!di->admin_tyents); 4084ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown di->admin_tyents = tyents_to_keep; 4085ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4086ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Bias all the location expressions. */ 4087ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("\n"); 4088ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("------ Biasing the location expressions ------\n" ); 4089ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4090ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n = VG_(sizeXA)( gexprs ); 4091ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n; i++) { 4092ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gexpr = *(GExpr**)VG_(indexXA)( gexprs, i ); 4093ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bias_GX( gexpr, di ); 4094ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4095ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4096ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("\n"); 4097ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("------ Acquired the following variables: ------\n\n"); 4098ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4099ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Park (pointers to) all the vars in an XArray, so we can look up 4100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown abstract origins quickly. The array is sorted (hence, looked-up 4101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown by) the .dioff fields. Since the .dioffs should be in strictly 4102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ascending order, there is no need to sort the array after 4103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown construction. The ascendingness is however asserted for. */ 4104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown dioff_lookup_tab 4105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.9", 4106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(dinfo_free), 4107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(TempVar*) ); 4108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(dioff_lookup_tab); 4109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n = VG_(sizeXA)( tempvars ); 4111436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Word first_primary_var = 0; 4112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng for (first_primary_var = 0; 4113436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov escn_debug_info_alt.szB/*really?*/ && first_primary_var < n; 4114663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng first_primary_var++) { 4115663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng varp = *(TempVar**)VG_(indexXA)( tempvars, first_primary_var ); 4116436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (varp->dioff < escn_debug_info.szB + escn_debug_types.szB) 4117663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng break; 4118663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 4119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n; i++) { 4120663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng varp = *(TempVar**)VG_(indexXA)( tempvars, (i + first_primary_var) % n ); 4121663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (i > first_primary_var) { 4122663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng varp2 = *(TempVar**)VG_(indexXA)( tempvars, 4123663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (i + first_primary_var - 1) % n ); 4124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* why should this hold? Only, I think, because we've 4125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown constructed the array by reading .debug_info sequentially, 4126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown and so the array .dioff fields should reflect that, and be 4127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown strictly ascending. */ 4128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(varp2->dioff < varp->dioff); 4129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(addToXA)( dioff_lookup_tab, &varp ); 4131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(setCmpFnXA)( dioff_lookup_tab, cmp_TempVar_by_dioff ); 4133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(sortXA)( dioff_lookup_tab ); /* POINTLESS; FIXME: rm */ 4134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Now visit each var. Collect up as much info as possible for 4136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown each var and hand it to ML_(addVar). */ 4137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n = VG_(sizeXA)( tempvars ); 4138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (j = 0; j < n; j++) { 4139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TyEnt* ent; 4140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varp = *(TempVar**)VG_(indexXA)( tempvars, j ); 4141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Possibly show .. */ 4143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (td3) { 4144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("<%lx> addVar: level %d: %s :: ", 4145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varp->dioff, 4146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varp->level, 4147436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov varp->name ? varp->name : "<anon_var>" ); 4148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (varp->typeR) { 4149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(pp_TyEnt_C_ishly)( tyents_to_keep, varp->typeR ); 4150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 4151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("NULL"); 4152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("\n Loc="); 4154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (varp->gexpr) { 4155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(pp_GX)(varp->gexpr); 4156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 4157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("NULL"); 4158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("\n"); 4160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (varp->fbGX) { 4161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)(" FrB="); 4162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(pp_GX)( varp->fbGX ); 4163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("\n"); 4164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 4165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)(" FrB=none\n"); 4166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)(" declared at: %s:%d\n", 4168436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov varp->fName ? varp->fName : "NULL", 4169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varp->fLine ); 4170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (varp->absOri != (UWord)D3_INVALID_CUOFF) 4171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)(" abstract origin: <%lx>\n", varp->absOri); 4172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Skip variables which have no location. These must be 4175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown abstract instances; they are useless as-is since with no 4176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown location they have no specified memory location. They will 4177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown presumably be referred to via the absOri fields of other 4178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown variables. */ 4179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!varp->gexpr) { 4180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" SKIP (no location)\n\n"); 4181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 4182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* So it has a location, at least. If it refers to some other 4185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown entry through its absOri field, pull in further info through 4186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that. */ 4187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (varp->absOri != (UWord)D3_INVALID_CUOFF) { 4188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool found; 4189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word ixFirst, ixLast; 4190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TempVar key; 4191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TempVar* keyp = &key; 4192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TempVar *varAI; 4193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(&key, 0, sizeof(key)); /* not necessary */ 4194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown key.dioff = varp->absOri; /* this is what we want to find */ 4195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown found = VG_(lookupXA)( dioff_lookup_tab, &keyp, 4196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown &ixFirst, &ixLast ); 4197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!found) { 4198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* barf("DW_AT_abstract_origin can't be resolved"); */ 4199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" SKIP (DW_AT_abstract_origin can't be resolved)\n\n"); 4200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown continue; 4201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* If the following fails, there is more than one entry with 4203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the same dioff. Which can't happen. */ 4204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ixFirst == ixLast); 4205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varAI = *(TempVar**)VG_(indexXA)( dioff_lookup_tab, ixFirst ); 4206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* stay sane */ 4207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(varAI); 4208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(varAI->dioff == varp->absOri); 4209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Copy what useful info we can. */ 4211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (varAI->typeR && !varp->typeR) 4212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varp->typeR = varAI->typeR; 4213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (varAI->name && !varp->name) 4214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varp->name = varAI->name; 4215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (varAI->fName && !varp->fName) 4216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varp->fName = varAI->fName; 4217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (varAI->fLine > 0 && varp->fLine == 0) 4218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varp->fLine = varAI->fLine; 4219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Give it a name if it doesn't have one. */ 4222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (!varp->name) 4223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varp->name = ML_(addStr)( di, "<anon_var>", -1 ); 4224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* So now does it have enough info to be useful? */ 4226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* NOTE: re typeR: this is a hack. If typeR is Te_UNKNOWN then 4227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown the type didn't get resolved. Really, in that case 4228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown something's broken earlier on, and should be fixed, rather 4229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown than just skipping the variable. */ 4230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ent = ML_(TyEnts__index_by_cuOff)( tyents_to_keep, 4231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tyents_to_keep_cache, 4232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varp->typeR ); 4233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* The next two assertions should be guaranteed by 4234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown our previous call to resolve_variable_types. */ 4235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ent); 4236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(ML_(TyEnt__is_type)(ent) || ent->tag == Te_UNKNOWN); 4237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (ent->tag == Te_UNKNOWN) continue; 4239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(varp->gexpr); 4241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(varp->name); 4242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(varp->typeR); 4243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(varp->level >= 0); 4244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Ok. So we're going to keep it. Call ML_(addVar) once for 4246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown each address range in which the variable exists. */ 4247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" ACQUIRE for range(s) "); 4248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { AddrRange oneRange; 4249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown AddrRange* varPcRanges; 4250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word nVarPcRanges; 4251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Set up to iterate over address ranges, however 4252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown represented. */ 4253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (varp->nRanges == 0 || varp->nRanges == 1) { 4254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(!varp->rngMany); 4255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (varp->nRanges == 0) { 4256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(varp->rngOneMin == 0); 4257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(varp->rngOneMax == 0); 4258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown nVarPcRanges = varp->nRanges; 4260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown oneRange.aMin = varp->rngOneMin; 4261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown oneRange.aMax = varp->rngOneMax; 4262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varPcRanges = &oneRange; 4263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 4264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(varp->rngMany); 4265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(varp->rngOneMin == 0); 4266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(varp->rngOneMax == 0); 4267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown nVarPcRanges = VG_(sizeXA)(varp->rngMany); 4268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(nVarPcRanges >= 2); 4269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(nVarPcRanges == (Word)varp->nRanges); 4270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varPcRanges = VG_(indexXA)(varp->rngMany, 0); 4271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (varp->level == 0) 4273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert( nVarPcRanges == 1 ); 4274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* and iterate */ 4275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < nVarPcRanges; i++) { 4276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr pcMin = varPcRanges[i].aMin; 4277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr pcMax = varPcRanges[i].aMax; 4278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(pcMin <= pcMax); 4279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Level 0 is the global address range. So at level 0 we 4280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown don't want to bias pcMin/pcMax; but at all other levels 4281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown we do since those are derived from svmas in the Dwarf 4282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown we're reading. Be paranoid ... */ 4283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (varp->level == 0) { 4284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(pcMin == (Addr)0); 4285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(pcMax == ~(Addr)0); 4286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 4287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* vg_assert(pcMin > (Addr)0); 4288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown No .. we can legitimately expect to see ranges like 4289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 0x0-0x11D (pre-biasing, of course). */ 4290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(pcMax < ~(Addr)0); 4291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Apply text biasing, for non-global variables. */ 4294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (varp->level > 0) { 4295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pcMin += di->text_debug_bias; 4296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pcMax += di->text_debug_bias; 4297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (i > 0 && (i%2) == 0) 4300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("\n "); 4301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("[%#lx,%#lx] ", pcMin, pcMax ); 4302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(addVar)( 4304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown di, varp->level, 4305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pcMin, pcMax, 4306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varp->name, varp->typeR, 4307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varp->gexpr, varp->fbGX, 4308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varp->fName, varp->fLine, td3 4309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 4310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("\n\n"); 4314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* and move on to the next var */ 4315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Now free all the TempVars */ 4318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown n = VG_(sizeXA)( tempvars ); 4319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (i = 0; i < n; i++) { 4320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown varp = *(TempVar**)VG_(indexXA)( tempvars, i ); 4321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(dinfo_free)(varp); 4322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(deleteXA)( tempvars ); 4324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tempvars = NULL; 4325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* and the temp lookup table */ 4327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(deleteXA)( dioff_lookup_tab ); 4328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* and the ranges tree. Note that we need to also free the XArrays 4330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown which constitute the keys, hence pass VG_(deleteXA) as a 4331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown key-finalizer. */ 4332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(deleteFM)( rangestree, (void(*)(UWord))VG_(deleteXA), NULL ); 4333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* and the tyents_to_keep cache */ 4335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(dinfo_free)( tyents_to_keep_cache ); 4336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tyents_to_keep_cache = NULL; 4337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4338663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng vg_assert( varparser.filenameTable == NULL ); 4339663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4340663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng /* And the signatured type hash. */ 4341663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng VG_(HT_destruct) ( signature_types, ML_(dinfo_free) ); 4342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* record the GExprs in di so they can be freed later */ 4344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(!di->admin_gexprs); 4345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown di->admin_gexprs = gexprs; 4346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 4350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 4351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- The "new" DWARF3 reader -- top level control logic ---*/ 4352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ---*/ 4353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 4354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic Bool d3rd_jmpbuf_valid = False; 4356436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic const HChar* d3rd_jmpbuf_reason = NULL; 4357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic VG_MINIMAL_JMP_BUF(d3rd_jmpbuf); 4358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4359436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic __attribute__((noreturn)) void barf ( const HChar* reason ) { 4360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(d3rd_jmpbuf_valid); 4361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d3rd_jmpbuf_reason = reason; 4362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VG_MINIMAL_LONGJMP(d3rd_jmpbuf); 4363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*NOTREACHED*/ 4364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(0); 4365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid 4369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownML_(new_dwarf3_reader) ( 4370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct _DebugInfo* di, 4371436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_info, DiSlice escn_debug_types, 4372436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_abbv, DiSlice escn_debug_line, 4373436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_str, DiSlice escn_debug_ranges, 4374436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_loc, DiSlice escn_debug_info_alt, 4375436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_abbv_alt, DiSlice escn_debug_line_alt, 4376436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov DiSlice escn_debug_str_alt 4377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown) 4378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 4379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile Int jumped; 4380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown volatile Bool td3 = di->trace_symtab; 4381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Run the _wrk function to read the dwarf3. If it succeeds, it 4383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown just returns normally. If there is any failure, it longjmp's 4384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown back here, having first set d3rd_jmpbuf_reason to something 4385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown useful. */ 4386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(d3rd_jmpbuf_valid == False); 4387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(d3rd_jmpbuf_reason == NULL); 4388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d3rd_jmpbuf_valid = True; 4390b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov jumped = VG_MINIMAL_SETJMP(d3rd_jmpbuf); 4391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (jumped == 0) { 4392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* try this ... */ 4393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown new_dwarf3_reader_wrk( di, barf, 4394436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov escn_debug_info, escn_debug_types, 4395436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov escn_debug_abbv, escn_debug_line, 4396436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov escn_debug_str, escn_debug_ranges, 4397436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov escn_debug_loc, escn_debug_info_alt, 4398436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov escn_debug_abbv_alt, escn_debug_line_alt, 4399436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov escn_debug_str_alt ); 4400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d3rd_jmpbuf_valid = False; 4401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("\n------ .debug_info reading was successful ------\n"); 4402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 4403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* It longjmp'd. */ 4404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d3rd_jmpbuf_valid = False; 4405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Can't longjump without giving some sort of reason. */ 4406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(d3rd_jmpbuf_reason != NULL); 4407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("\n------ .debug_info reading failed ------\n"); 4409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ML_(symerr)(di, True, d3rd_jmpbuf_reason); 4411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d3rd_jmpbuf_valid = False; 4414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d3rd_jmpbuf_reason = NULL; 4415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 4416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --- Unused code fragments which might be useful one day. --- */ 4420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if 0 4422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Read the arange tables */ 4423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_SYMTAB("\n"); 4424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_SYMTAB("\n------ The contents of .debug_arange ------\n"); 4425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown init_Cursor( &aranges, debug_aranges_img, 4426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown debug_aranges_sz, 0, barf, 4427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "Overrun whilst reading .debug_aranges section" ); 4428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 4429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong len, d_i_offset; 4430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool is64; 4431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UShort version; 4432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar asize, segsize; 4433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (is_at_end_Cursor( &aranges )) 4435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown break; 4436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Read one arange thingy */ 4437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* initial_length field */ 4438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown len = get_Initial_Length( &is64, &aranges, 4439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "in .debug_aranges: invalid initial-length field" ); 4440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown version = get_UShort( &aranges ); 4441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d_i_offset = get_Dwarfish_UWord( &aranges, is64 ); 4442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown asize = get_UChar( &aranges ); 4443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown segsize = get_UChar( &aranges ); 4444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" Length: %llu\n", len); 4445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" Version: %d\n", (Int)version); 4446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" Offset into .debug_info: %llx\n", d_i_offset); 4447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" Pointer Size: %d\n", (Int)asize); 4448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" Segment Size: %d\n", (Int)segsize); 4449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3("\n"); 4450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" Address Length\n"); 4451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while ((get_position_of_Cursor( &aranges ) % (2 * asize)) > 0) { 4453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (void)get_UChar( & aranges ); 4454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown while (True) { 4456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong address = get_Dwarfish_UWord( &aranges, asize==8 ); 4457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong length = get_Dwarfish_UWord( &aranges, asize==8 ); 4458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_D3(" 0x%016llx 0x%llx\n", address, length); 4459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (address == 0 && length == 0) break; 4460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 4462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown TRACE_SYMTAB("\n"); 4463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 4464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif // defined(VGO_linux) || defined(VGO_darwin) 4466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 4468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end ---*/ 4469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 4470