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