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