priv_storage.h revision ed07e00d438c74b7a23c01bfffde77e3968305e4
1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Format-neutral storage of and querying of info acquired from ---*/
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- ELF/XCOFF stabs/dwarf1/dwarf2 debug info.                    ---*/
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*---                                               priv_storage.h ---*/
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This file is part of Valgrind, a dynamic binary instrumentation
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   framework.
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Copyright (C) 2000-2010 Julian Seward
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      jseward@acm.org
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is free software; you can redistribute it and/or
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   modify it under the terms of the GNU General Public License as
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   published by the Free Software Foundation; either version 2 of the
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   License, or (at your option) any later version.
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This program is distributed in the hope that it will be useful, but
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   WITHOUT ANY WARRANTY; without even the implied warranty of
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   General Public License for more details.
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   You should have received a copy of the GNU General Public License
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   along with this program; if not, write to the Free Software
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   02111-1307, USA.
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The GNU General Public License is contained in the file COPYING.
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Stabs reader greatly improved by Nick Nethercote, Apr 02.
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   This module was also extensively hacked on by Jeremy Fitzhardinge
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   and Tom Hughes.
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* See comment at top of debuginfo.c for explanation of
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   the _svma / _avma / _image / _bias naming scheme.
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Note this is not freestanding; needs pub_core_xarray.h and
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   priv_tytypes.h to be included before it. */
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifndef __PRIV_STORAGE_H
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __PRIV_STORAGE_H
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------- SYMBOLS --------------------- */
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A structure to hold an ELF/XCOFF symbol (very crudely). */
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr  addr;    /* lowest address of entity */
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr  tocptr;  /* ppc64-linux only: value that R2 should have */
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar *name;   /* name */
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // XXX: this could be shrunk (on 32-bit platforms) by using 31 bits for
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // the size and 1 bit for the isText.  If you do this, make sure that
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // all assignments to isText use 0 or 1 (or True or False), and that a
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      // positive number larger than 1 is never used to represent True.
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt  size;    /* size in bytes */
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool  isText;
60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool  isIFunc; /* symbol is an indirect function? */
61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiSym;
63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------- SRCLOCS --------------------- */
65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Line count at which overflow happens, due to line numbers being
67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   stored as shorts in `struct nlist' in a.out.h. */
68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define LINENO_OVERFLOW (1 << (sizeof(short) * 8))
69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define LINENO_BITS     20
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define LOC_SIZE_BITS  (32 - LINENO_BITS)
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MAX_LINENO     ((1 << LINENO_BITS) - 1)
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Unlikely to have any lines with instruction ranges > 4096 bytes */
75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MAX_LOC_SIZE   ((1 << LOC_SIZE_BITS) - 1)
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Number used to detect line number overflows; if one line is
78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   60000-odd smaller than the previous, it was probably an overflow.
79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define OVERFLOW_DIFFERENCE     (LINENO_OVERFLOW - 5000)
81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A structure to hold addr-to-source info for a single line.  There
83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  can be a lot of these, hence the dense packing. */
84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Word 1 */
87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr   addr;               /* lowest address for this line */
88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Word 2 */
89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UShort size:LOC_SIZE_BITS; /* # bytes; we catch overflows of this */
90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt   lineno:LINENO_BITS; /* source line number, or zero */
91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Word 3 */
92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar*  filename;          /* source filename */
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Word 4 */
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar*  dirname;           /* source directory name */
95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiLoc;
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------- CF INFO --------------------- */
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* DiCfSI: a structure to summarise DWARF2/3 CFA info for the code
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   address range [base .. base+len-1].
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   On x86 and amd64 ("IA"), if you know ({e,r}sp, {e,r}bp, {e,r}ip) at
104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   some point and {e,r}ip is in the range [base .. base+len-1], it
105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tells you how to calculate ({e,r}sp, {e,r}bp) for the caller of the
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   current frame and also ra, the return address of the current frame.
107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   First off, calculate CFA, the Canonical Frame Address, thusly:
109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     cfa = case cfa_how of
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIC_IA_SPREL -> {e,r}sp + cfa_off
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIC_IA_BPREL -> {e,r}bp + cfa_off
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_IA_EXPR  -> expr whose index is in cfa_off
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Once that is done, the previous frame's {e,r}sp/{e,r}bp values and
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   this frame's {e,r}ra value can be calculated like this:
117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     old_{e,r}sp/{e,r}bp/ra
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         = case {e,r}sp/{e,r}bp/ra_how of
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_UNKNOWN   -> we don't know, sorry
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_SAME      -> same as it was before (sp/fp only)
122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_CFAREL    -> cfa + sp/bp/ra_off
123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_MEMCFAREL -> *( cfa + sp/bp/ra_off )
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_EXPR      -> expr whose index is in sp/bp/ra_off
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   On ARM it's pretty much the same, except we have more registers to
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   keep track of:
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     cfa = case cfa_how of
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIC_R13REL -> r13 + cfa_off
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIC_R12REL -> r12 + cfa_off
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIC_R11REL -> r11 + cfa_off
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIC_R7REL  -> r7  + cfa_off
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_EXPR   -> expr whose index is in cfa_off
135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     old_r14/r13/r12/r11/r7/ra
137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         = case r14/r13/r12/r11/r7/ra_how of
138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_UNKNOWN   -> we don't know, sorry
139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_SAME      -> same as it was before (r14/r13/r12/r11/r7 only)
140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_CFAREL    -> cfa + r14/r13/r12/r11/r7/ra_off
141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_MEMCFAREL -> *( cfa + r14/r13/r12/r11/r7/ra_off )
142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_EXPR      -> expr whose index is in r14/r13/r12/r11/r7/ra_off
143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIC_IA_SPREL     ((UChar)1)
146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIC_IA_BPREL     ((UChar)2)
147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIC_IA_EXPR      ((UChar)3)
148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIC_ARM_R13REL   ((UChar)4)
149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIC_ARM_R12REL   ((UChar)5)
150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIC_ARM_R11REL   ((UChar)6)
151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIC_ARM_R7REL    ((UChar)7)
152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIC_EXPR         ((UChar)8)  /* all targets */
153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIR_UNKNOWN      ((UChar)64)
155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIR_SAME         ((UChar)65)
156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIR_CFAREL       ((UChar)66)
157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIR_MEMCFAREL    ((UChar)67)
158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIR_EXPR         ((UChar)68)
159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGA_x86) || defined(VGA_amd64)
161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr  base;
164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt  len;
165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar cfa_how; /* a CFIC_IA value */
166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar ra_how;  /* a CFIR_ value */
167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar sp_how;  /* a CFIR_ value */
168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar bp_how;  /* a CFIR_ value */
169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   cfa_off;
170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   ra_off;
171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   sp_off;
172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   bp_off;
173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiCfSI;
175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGA_arm)
176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr  base;
179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt  len;
180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar cfa_how; /* a CFIC_ value */
181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar ra_how;  /* a CFIR_ value */
182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar r14_how; /* a CFIR_ value */
183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar r13_how; /* a CFIR_ value */
184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar r12_how; /* a CFIR_ value */
185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar r11_how; /* a CFIR_ value */
186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar r7_how;  /* a CFIR_ value */
187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   cfa_off;
188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   ra_off;
189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   r14_off;
190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   r13_off;
191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   r12_off;
192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   r11_off;
193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   r7_off;
194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiCfSI;
196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGA_ppc32) || defined(VGA_ppc64)
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Just have a struct with the common fields in, so that code that
198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   processes the common fields doesn't have to be ifdef'd against
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VGP_/VGA_ symbols.  These are not used in any way on ppc32/64-linux
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   at the moment. */
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr  base;
204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt  len;
205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar cfa_how; /* a CFIC_ value */
206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar ra_how;  /* a CFIR_ value */
207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   cfa_off;
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   ra_off;
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiCfSI;
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  error "Unknown arch"
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   enum {
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Cop_Add=0x321,
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Cop_Sub,
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Cop_And,
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Cop_Mul
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   CfiOp;
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   enum {
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Creg_IA_SP=0x213,
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Creg_IA_BP,
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Creg_IA_IP,
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Creg_ARM_R13,
231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Creg_ARM_R12,
232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Creg_ARM_R15,
233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Creg_ARM_R14
234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   CfiReg;
236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   enum {
239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Cex_Undef=0x123,
240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Cex_Deref,
241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Cex_Const,
242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Cex_Binop,
243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Cex_CfiReg,
244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Cex_DwReg
245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   CfiExprTag;
247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CfiExprTag tag;
251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      union {
252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } Undef;
254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Int ixAddr;
256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } Deref;
257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UWord con;
259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } Const;
260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            CfiOp op;
262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Int ixL;
263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Int ixR;
264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } Binop;
265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            CfiReg reg;
267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } CfiReg;
268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Int reg;
270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } DwReg;
271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Cex;
273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   CfiExpr;
275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Int ML_(CfiExpr_Undef) ( XArray* dst );
277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Int ML_(CfiExpr_Deref) ( XArray* dst, Int ixAddr );
278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Int ML_(CfiExpr_Const) ( XArray* dst, UWord con );
279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Int ML_(CfiExpr_Binop) ( XArray* dst, CfiOp op, Int ixL, Int ixR );
280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Int ML_(CfiExpr_CfiReg)( XArray* dst, CfiReg reg );
281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Int ML_(CfiExpr_DwReg) ( XArray* dst, Int reg );
282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ML_(ppCfiExpr)( XArray* src, Int ix );
284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------- FPO INFO (Windows PE) -------------- */
286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* for apps using Wine: MSVC++ PDB FramePointerOmitted: somewhat like
288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   a primitive CFI */
289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct _FPO_DATA {  /* 16 bytes */
291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt   ulOffStart; /* offset of 1st byte of function code */
292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt   cbProcSize; /* # bytes in function */
293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt   cdwLocals;  /* # bytes/4 in locals */
294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UShort cdwParams;  /* # bytes/4 in params */
295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar  cbProlog;   /* # bytes in prolog */
296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar  cbRegs :3;  /* # regs saved */
297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar  fHasSEH:1;  /* Structured Exception Handling */
298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar  fUseBP :1;  /* EBP has been used */
299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar  reserved:1;
300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar  cbFrame:2;  /* frame type */
301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   FPO_DATA;
303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PDB_FRAME_FPO  0
305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PDB_FRAME_TRAP 1
306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PDB_FRAME_TSS  2
307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------- VARIABLES --------------------- */
309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr    aMin;
313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr    aMax;
314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      XArray* /* of DiVariable */ vars;
315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiAddrRange;
317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar* name;  /* in DebugInfo.strchunks */
321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord  typeR; /* a cuOff */
322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      GExpr* gexpr; /* on DebugInfo.gexprs list */
323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      GExpr* fbGX;  /* SHARED. */
324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar* fileName; /* where declared; may be NULL. in
325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          DebugInfo.strchunks */
326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int    lineNo;   /* where declared; may be zero. */
327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiVariable;
329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownWord
331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownML_(cmp_for_DiAddrRange_range) ( const void* keyV, const void* elemV );
332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------- DEBUGINFO --------------------- */
334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This is the top-level data type.  It's a structure which contains
336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   information pertaining to one mapped ELF object.  This type is
337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   exported only abstractly - in pub_tool_debuginfo.h. */
338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SEGINFO_STRCHUNKSIZE (64*1024)
340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _DebugInfo {
342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Admin stuff */
344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct _DebugInfo* next;   /* list of DebugInfos */
346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool               mark;   /* marked for deletion? */
347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* An abstract handle, which can be used by entities outside of
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      m_debuginfo to (in an abstract datatype sense) refer to this
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct _DebugInfo.  A .handle of zero is invalid; valid handles
351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      are 1 and above.  The same handle is never issued twice (in any
352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      given run of Valgrind), so a handle becomes invalid when the
353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      associated struct _DebugInfo is discarded, and remains invalid
354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      forever thereafter.  The .handle field is set as soon as this
355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      structure is allocated. */
356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ULong handle;
357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Used for debugging only - indicate what stuff to dump whilst
359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      reading stuff into the seginfo.  Are computed as early in the
360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lifetime of the DebugInfo as possible -- at the point when it is
361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      created.  Use these when deciding what to spew out; do not use
362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the global VG_(clo_blah) flags. */
363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool trace_symtab; /* symbols, our style */
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool trace_cfi;    /* dwarf frame unwind, our style */
366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool ddump_syms;   /* mimic /usr/bin/readelf --syms */
367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool ddump_line;   /* mimic /usr/bin/readelf --debug-dump=line */
368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool ddump_frames; /* mimic /usr/bin/readelf --debug-dump=frames */
369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Fields that must be filled in before we can start reading
371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      anything from the ELF file.  These fields are filled in by
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(di_notify_mmap) and its immediate helpers. */
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar* filename; /* in mallocville (VG_AR_DINFO) */
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar* memname;  /* also in VG_AR_DINFO.  AIX5 only: .a member name */
376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool  have_rx_map; /* did we see a r?x mapping yet for the file? */
378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool  have_rw_map; /* did we see a rw? mapping yet for the file? */
379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr  rx_map_avma; /* these fields record the file offset, length */
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT rx_map_size; /* and map address of the r?x mapping we believe */
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OffT  rx_map_foff; /* is the .text segment mapping */
383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr  rw_map_avma; /* ditto, for the rw? mapping we believe is the */
385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT rw_map_size; /* .data segment mapping */
386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   OffT  rw_map_foff;
387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Once both a rw? and r?x mapping for .filename have been
389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      observed, we can go on to read the symbol tables and debug info.
390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      .have_dinfo flags when that has happened. */
391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* If have_dinfo is False, then all fields except "*rx_map*" and
392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      "*rw_map*" are invalid and should not be consulted. */
393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool  have_dinfo; /* initially False */
394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* All the rest of the fields in this structure are filled in once
396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      we have committed to reading the symbols and debug info (that
397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      is, at the point where .have_dinfo is set to True). */
398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* The file's soname.  FIXME: ensure this is always allocated in
400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_AR_DINFO. */
401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UChar* soname;
402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Description of some important mapped segments.  The presence or
404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      absence of the mapping is denoted by the _present field, since
405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      in some obscure circumstances (to do with data/sdata/bss) it is
406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      possible for the mapping to be present but have zero size.
407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Certainly text_ is mandatory on all platforms; not sure about
408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the rest though.
409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      --------------------------------------------------------
411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Comment_on_IMPORTANT_CFSI_REPRESENTATIONAL_INVARIANTS: we require that
413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      either (rx_map_size == 0 && cfsi == NULL) (the degenerate case)
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      or the normal case, which is the AND of the following:
417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (0) rx_map_size > 0
418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (1) no two DebugInfos with rx_map_size > 0
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          have overlapping [rx_map_avma,+rx_map_size)
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (2) [cfsi_minavma,cfsi_maxavma] does not extend
421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          beyond [rx_map_avma,+rx_map_size); that is, the former is a
422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          subrange or equal to the latter.
423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (3) all DiCfSI in the cfsi array all have ranges that fall within
424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown          [rx_map_avma,+rx_map_size).
425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (4) all DiCfSI in the cfsi array are non-overlapping
426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      The cumulative effect of these restrictions is to ensure that
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      all the DiCfSI records in the entire system are non overlapping.
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Hence any address falls into either exactly one DiCfSI record,
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      or none.  Hence it is safe to cache the results of searches for
431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      DiCfSI records.  This is the whole point of these restrictions.
432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      The caching of DiCfSI searches is done in VG_(use_CF_info).  The
433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cache is flushed after any change to debugInfo_list.  DiCfSI
434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      searches are cached because they are central to stack unwinding
435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      on amd64-linux.
436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Where are these invariants imposed and checked?
438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      They are checked after a successful read of debuginfo into
440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a DebugInfo*, in check_CFSI_related_invariants.
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (1) is not really imposed anywhere.  We simply assume that the
443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kernel will not map the text segments from two different objects
444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      into the same space.  Sounds reasonable.
445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (2) follows from (4) and (3).  It is ensured by canonicaliseCFI.
447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (3) is ensured by ML_(addDiCfSI).
448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (4) is ensured by canonicaliseCFI.
449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      --------------------------------------------------------
451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Comment_on_DEBUG_SVMA_and_DEBUG_BIAS_fields:
453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      The _debug_{svma,bias} fields were added as part of a fix to
455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      #185816.  The problem encompassed in that bug report was that it
456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      wasn't correct to use apply the bias values deduced for a
457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      primary object to its associated debuginfo object, because the
458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      debuginfo object (or the primary) could have been prelinked to a
459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      different SVMA.  Hence debuginfo and primary objects need to
460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      have their own biases.
461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ------ JRS: (referring to r9329): ------
463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Let me see if I understand the workings correctly.  Initially
464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the _debug_ values are set to the same values as the "normal"
465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ones, as there's a bunch of bits of code like this (in
466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      readelf.c)
467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         di->text_svma = svma;
469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ...
470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         di->text_bias = rx_bias;
471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         di->text_debug_svma = svma;
472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         di->text_debug_bias = rx_bias;
473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      If a debuginfo object subsequently shows up then the
475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _debug_svma/bias are set for the debuginfo object.  Result is
476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      that if there's no debuginfo object then the values are the same
477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      as the primary-object values, and if there is a debuginfo object
478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      then they will (or at least may) be different.
479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Then when we need to actually bias something, we'll have to
481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      decide whether to use the primary bias or the debuginfo bias.
482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      And the strategy is to use the primary bias for ELF symbols but
483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the debuginfo bias for anything pulled out of Dwarf.
484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ------ THH: ------
486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Correct - the debug_svma and bias values apply to any address
487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      read from the debug data regardless of where that debug data is
488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      stored and the other values are used for addresses from other
489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      places (primarily the symbol table).
490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ------ JRS: ------
492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ok; so this was my only area of concern.  Are there any
493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      corner-case scenarios where this wouldn't be right?  It sounds
494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      like we're assuming the ELF symbols come from the primary object
495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      and, if there is a debug object, then all the Dwarf comes from
496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      there.  But what if (eg) both symbols and Dwarf come from the
497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      debug object?  Is that even possible or allowable?
498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ------ THH: ------
500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      You may have a point...
501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      The current logic is to try and take any one set of data from
503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      either the base object or the debug object. There are four sets
504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      of data we consider:
505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         - Symbol Table
507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         - Stabs
508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         - DWARF1
509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         - DWARF2
510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      If we see the primary section for a given set in the base object
512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      then we ignore all sections relating to that set in the debug
513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      object.
514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Now in principle if we saw a secondary section (like debug_line
516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      say) in the base object, but not the main section (debug_info in
517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      this case) then we would take debug_info from the debug object
518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      but would use the debug_line from the base object unless we saw
519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a replacement copy in the debug object. That's probably unlikely
520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      however.
521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      A bigger issue might be, as you say, the symbol table as we will
523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      pick that up from the debug object if it isn't in the base. The
524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dynamic symbol table will always have to be in the base object
525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      though so we will have to be careful when processing symbols to
526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      know which table we are reading in that case.
527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      What we probably need to do is tell read_elf_symtab which object
529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the symbols it is being asked to read came from.
530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (A followup patch to deal with this was committed in r9469).
532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   */
533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .text */
534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool     text_present;
535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     text_avma;
536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     text_svma;
537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT    text_size;
538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT text_bias;
539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     text_debug_svma;
540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT text_debug_bias;
541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .data */
542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool     data_present;
543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     data_svma;
544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     data_avma;
545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT    data_size;
546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT data_bias;
547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     data_debug_svma;
548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT data_debug_bias;
549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .sdata */
550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool     sdata_present;
551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     sdata_svma;
552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     sdata_avma;
553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT    sdata_size;
554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT sdata_bias;
555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     sdata_debug_svma;
556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT sdata_debug_bias;
557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .rodata */
558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool     rodata_present;
559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     rodata_svma;
560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     rodata_avma;
561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT    rodata_size;
562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT rodata_bias;
563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     rodata_debug_svma;
564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT rodata_debug_bias;
565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .bss */
566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool     bss_present;
567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     bss_svma;
568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     bss_avma;
569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT    bss_size;
570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT bss_bias;
571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     bss_debug_svma;
572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT bss_debug_bias;
573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .sbss */
574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool     sbss_present;
575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     sbss_svma;
576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     sbss_avma;
577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT    sbss_size;
578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT sbss_bias;
579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     sbss_debug_svma;
580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT sbss_debug_bias;
581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .plt */
582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool   plt_present;
583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr	  plt_avma;
584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT  plt_size;
585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .got */
586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool   got_present;
587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr   got_avma;
588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT  got_size;
589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .got.plt */
590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool   gotplt_present;
591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr   gotplt_avma;
592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT  gotplt_size;
593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .opd -- needed on ppc64-linux for finding symbols */
594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool   opd_present;
595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr   opd_avma;
596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT  opd_size;
597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .ehframe -- needed on amd64-linux for stack unwinding */
598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool   ehframe_present;
599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr   ehframe_avma;
600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT  ehframe_size;
601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Sorted tables of stuff we snarfed from the file.  This is the
603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      eventual product of reading the debug info.  All this stuff
604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lives in VG_AR_DINFO. */
605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* An expandable array of symbols. */
607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiSym*  symtab;
608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord   symtab_used;
609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord   symtab_size;
610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* An expandable array of locations. */
611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiLoc*  loctab;
612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord   loctab_used;
613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord   loctab_size;
614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* An expandable array of CFI summary info records.  Also includes
615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      summary address bounds, showing the min and max address covered
616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      by any of the records, as an aid to fast searching.  And, if the
617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      records require any expression nodes, they are stored in
618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cfsi_exprs. */
619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiCfSI* cfsi;
620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord   cfsi_used;
621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord   cfsi_size;
622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr    cfsi_minavma;
623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr    cfsi_maxavma;
624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   XArray* cfsi_exprs; /* XArray of CfiExpr */
625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Optimized code under Wine x86: MSVC++ PDB FramePointerOmitted
627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      data.  Non-expandable array, hence .size == .used. */
628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   FPO_DATA* fpo;
629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord     fpo_size;
630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr      fpo_minavma;
631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr      fpo_maxavma;
632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Expandable arrays of characters -- the string table.  Pointers
634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      into this are stable (the arrays are not reallocated). */
635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct strchunk {
636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt   strtab_used;
637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct strchunk* next;
638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar  strtab[SEGINFO_STRCHUNKSIZE];
639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } *strchunks;
640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Variable scope information, as harvested from Dwarf3 files.
642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      In short it's an
644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         array of (array of PC address ranges and variables)
646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      The outer array indexes over scopes, with Entry 0 containing
648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      information on variables which exist for any value of the program
649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      counter (PC) -- that is, the outermost scope.  Entries 1, 2, 3,
650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      etc contain information on increasinly deeply nested variables.
651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Each inner array is an array of (an address range, and a set
653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      of variables that are in scope over that address range).
654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      The address ranges may not overlap.
656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Since Entry 0 in the outer array holds information on variables
658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      that exist for any value of the PC (that is, global vars), it
659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      follows that Entry 0's inner array can only have one address
660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      range pair, one that covers the entire address space.
661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   */
662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   XArray* /* of OSet of DiAddrRange */varinfo;
663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* These are arrays of the relevant typed objects, held here
665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      partially for the purposes of visiting each object exactly once
666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      when we need to delete them. */
667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* An array of TyEnts.  These are needed to make sense of any types
669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      in the .varinfo.  Also, when deleting this DebugInfo, we must
670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      first traverse this array and throw away malloc'd stuff hanging
671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      off it -- by calling ML_(TyEnt__make_EMPTY) on each entry. */
672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   XArray* /* of TyEnt */ admin_tyents;
673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* An array of guarded DWARF3 expressions. */
675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   XArray* admin_gexprs;
676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------- functions --------------------- */
679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------ Adding ------ */
681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a symbol to si's symbol table. */
683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ML_(addSym) ( struct _DebugInfo* di, DiSym* sym );
684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a line-number record to a DebugInfo. */
686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern
687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ML_(addLineInfo) ( struct _DebugInfo* di,
688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        UChar*   filename,
689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        UChar*   dirname,  /* NULL is allowable */
690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        Addr this, Addr next, Int lineno, Int entry);
691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Shrink completed tables to save memory. */
693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern
694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ML_(shrinkSym) ( struct _DebugInfo *di );
695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern
696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ML_(shrinkLineInfo) ( struct _DebugInfo *di );
697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a CFI summary record.  The supplied DiCfSI is copied. */
699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ML_(addDiCfSI) ( struct _DebugInfo* di, DiCfSI* cfsi );
700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a string to the string table of a DebugInfo.  If len==-1,
702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(addStr) will itself measure the length of the string. */
703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern UChar* ML_(addStr) ( struct _DebugInfo* di, UChar* str, Int len );
704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ML_(addVar)( struct _DebugInfo* di,
706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         Int    level,
707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         Addr   aMin,
708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         Addr   aMax,
709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         UChar* name,
710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         UWord  typeR, /* a cuOff */
711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         GExpr* gexpr,
712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         GExpr* fbGX, /* SHARED. */
713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         UChar* fileName, /* where decl'd - may be NULL */
714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         Int    lineNo, /* where decl'd - may be zero */
715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         Bool   show );
716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Canonicalise the tables held by 'di', in preparation for use.  Call
718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   this after finishing adding entries to these tables. */
719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ML_(canonicaliseTables) ( struct _DebugInfo* di );
720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Canonicalise the call-frame-info table held by 'di', in preparation
722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for use. This is called by ML_(canonicaliseTables) but can also be
723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   called on it's own to sort just this table. */
724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ML_(canonicaliseCFI) ( struct _DebugInfo* di );
725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------ Searching ------ */
727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Find a symbol-table index containing the specified pointer, or -1
729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if not found.  Binary search.  */
730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Word ML_(search_one_symtab) ( struct _DebugInfo* di, Addr ptr,
731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                     Bool match_anywhere_in_sym,
732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                     Bool findText );
733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Find a location-table index containing the specified pointer, or -1
735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if not found.  Binary search.  */
736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Word ML_(search_one_loctab) ( struct _DebugInfo* di, Addr ptr );
737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Find a CFI-table index containing the specified pointer, or -1 if
739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   not found.  Binary search.  */
740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Word ML_(search_one_cfitab) ( struct _DebugInfo* di, Addr ptr );
741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Find a FPO-table index containing the specified pointer, or -1
743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if not found.  Binary search.  */
744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Word ML_(search_one_fpotab) ( struct _DebugInfo* di, Addr ptr );
745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------ Misc ------ */
747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Show a non-fatal debug info reading error.  Use vg_panic if
749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   terminal.  'serious' errors are always shown, not 'serious' ones
750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   are shown only at verbosity level 2 and above. */
751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern
752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ML_(symerr) ( struct _DebugInfo* di, Bool serious, HChar* msg );
753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print a symbol. */
755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ML_(ppSym) ( Int idx, DiSym* sym );
756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print a call-frame-info summary. */
758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ML_(ppDiCfSI) ( XArray* /* of CfiExpr */ exprs, DiCfSI* si );
759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define TRACE_SYMTAB(format, args...) \
762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (di->trace_symtab) { VG_(printf)(format, ## args); }
763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* ndef __PRIV_STORAGE_H */
766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end                                                          ---*/
769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
770