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
12436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   Copyright (C) 2000-2013 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
46436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "pub_core_basics.h"   // Addr
47436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "pub_core_xarray.h"   // XArray
48436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "priv_d3basics.h"     // GExpr et al.
49436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "priv_image.h"        // DiCursor
50436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------- SYMBOLS --------------------- */
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* A structure to hold an ELF/MachO symbol (very crudely).  Usually
54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   the symbol only has one name, which is stored in ::pri_name, and
55b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ::sec_names is NULL.  If there are other names, these are stored in
56b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ::sec_names, which is a NULL terminated vector holding the names.
57b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   The vector is allocated in VG_AR_DINFO, the names themselves live
58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   in DebugInfo::strchunks.
59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   From the point of view of ELF, the primary vs secondary distinction
61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   is artificial: they are all just names associated with the address,
62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   none of which has higher precedence than any other.  However, from
63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   the point of view of mapping an address to a name to display to the
64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   user, we need to choose one "preferred" name, and so that might as
65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   well be installed as the pri_name, whilst all others can live in
66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sec_names[].  This has the convenient side effect that, in the
67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   common case where there is only one name for the address,
68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sec_names[] does not need to be allocated.
69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/
70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Addr    addr;    /* lowest address of entity */
73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Addr    tocptr;  /* ppc64-linux only: value that R2 should have */
74436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      HChar*  pri_name;  /* primary name, never NULL */
75436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      HChar** sec_names; /* NULL, or a NULL term'd array of other names */
76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      // XXX: this could be shrunk (on 32-bit platforms) by using 30
77b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      // bits for the size and 1 bit each for isText and isIFunc.  If you
78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      // do this, make sure that all assignments to the latter two use
79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      // 0 or 1 (or True or False), and that a positive number larger
80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      // than 1 is never used to represent True.
81b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UInt    size;    /* size in bytes */
82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Bool    isText;
83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Bool    isIFunc; /* symbol is an indirect function? */
84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiSym;
86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------- SRCLOCS --------------------- */
88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Line count at which overflow happens, due to line numbers being
90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   stored as shorts in `struct nlist' in a.out.h. */
91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define LINENO_OVERFLOW (1 << (sizeof(short) * 8))
92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define LINENO_BITS     20
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define LOC_SIZE_BITS  (32 - LINENO_BITS)
95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MAX_LINENO     ((1 << LINENO_BITS) - 1)
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Unlikely to have any lines with instruction ranges > 4096 bytes */
98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define MAX_LOC_SIZE   ((1 << LOC_SIZE_BITS) - 1)
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Number used to detect line number overflows; if one line is
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   60000-odd smaller than the previous, it was probably an overflow.
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define OVERFLOW_DIFFERENCE     (LINENO_OVERFLOW - 5000)
104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A structure to hold addr-to-source info for a single line.  There
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  can be a lot of these, hence the dense packing. */
107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Word 1 */
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr   addr;               /* lowest address for this line */
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Word 2 */
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UShort size:LOC_SIZE_BITS; /* # bytes; we catch overflows of this */
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt   lineno:LINENO_BITS; /* source line number, or zero */
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Word 3 */
115436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      const HChar* filename;     /* source filename */
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Word 4 */
117436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      const HChar* dirname;      /* source directory name */
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiLoc;
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------- CF INFO --------------------- */
122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* DiCfSI: a structure to summarise DWARF2/3 CFA info for the code
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   address range [base .. base+len-1].
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   On x86 and amd64 ("IA"), if you know ({e,r}sp, {e,r}bp, {e,r}ip) at
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   some point and {e,r}ip is in the range [base .. base+len-1], it
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tells you how to calculate ({e,r}sp, {e,r}bp) for the caller of the
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   current frame and also ra, the return address of the current frame.
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   First off, calculate CFA, the Canonical Frame Address, thusly:
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     cfa = case cfa_how of
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIC_IA_SPREL -> {e,r}sp + cfa_off
135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIC_IA_BPREL -> {e,r}bp + cfa_off
136436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov              CFIC_EXPR     -> expr whose index is in cfa_off
137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Once that is done, the previous frame's {e,r}sp/{e,r}bp values and
139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   this frame's {e,r}ra value can be calculated like this:
140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     old_{e,r}sp/{e,r}bp/ra
142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         = case {e,r}sp/{e,r}bp/ra_how of
143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_UNKNOWN   -> we don't know, sorry
144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_SAME      -> same as it was before (sp/fp only)
145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_CFAREL    -> cfa + sp/bp/ra_off
146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_MEMCFAREL -> *( cfa + sp/bp/ra_off )
147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_EXPR      -> expr whose index is in sp/bp/ra_off
148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   On ARM it's pretty much the same, except we have more registers to
150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   keep track of:
151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     cfa = case cfa_how of
153436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov              CFIC_ARM_R13REL -> r13 + cfa_off
154436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov              CFIC_ARM_R12REL -> r12 + cfa_off
155436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov              CFIC_ARM_R11REL -> r11 + cfa_off
156436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov              CFIC_ARM_R7REL  -> r7  + cfa_off
157436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov              CFIR_EXPR       -> expr whose index is in cfa_off
158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     old_r14/r13/r12/r11/r7/ra
160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         = case r14/r13/r12/r11/r7/ra_how of
161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_UNKNOWN   -> we don't know, sorry
162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_SAME      -> same as it was before (r14/r13/r12/r11/r7 only)
163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_CFAREL    -> cfa + r14/r13/r12/r11/r7/ra_off
164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_MEMCFAREL -> *( cfa + r14/r13/r12/r11/r7/ra_off )
165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              CFIR_EXPR      -> expr whose index is in r14/r13/r12/r11/r7/ra_off
166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
167436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   On ARM64:
168436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
169436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     cfa = case cfa_how of
170436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov              CFIC_ARM64_SPREL  -> sp + cfa_off
171436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov              CFIC_ARM64_X29REL -> x29 + cfa_off
172436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov              CFIC_EXPR         -> expr whose index is in cfa_off
173436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
174436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov     old_sp/x30/x29/ra
175436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         = case sp/x30/x29/ra_how of
176436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov              CFIR_UNKNOWN   -> we don't know, sorry
177436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov              CFIR_SAME      -> same as it was before
178436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov              CFIR_CFAREL    -> cfa + sp/x30/x29/ra_how
179436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov              CFIR_MEMCFAREL -> *( cfa + sp/x30/x29/ra_how )
180436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov              CFIR_EXPR      -> expr whose index is in sp/x30/x29/ra_off
181436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   On s390x we have a similar logic as x86 or amd64. We need the stack pointer
183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   (r15), the frame pointer r11 (like BP) and together with the instruction
184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   address in the PSW we can calculate the previous values:
185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     cfa = case cfa_how of
186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov              CFIC_IA_SPREL -> r15 + cfa_off
187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov              CFIC_IA_BPREL -> r11 + cfa_off
188436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov              CFIC_EXPR     -> expr whose index is in cfa_off
189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     old_sp/fp/ra
191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         = case sp/fp/ra_how of
192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov              CFIR_UNKNOWN   -> we don't know, sorry
193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov              CFIR_SAME      -> same as it was before (sp/fp only)
194b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov              CFIR_CFAREL    -> cfa + sp/fp/ra_off
195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov              CFIR_MEMCFAREL -> *( cfa + sp/fp/ra_off )
196b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov              CFIR_EXPR      -> expr whose index is in sp/fp/ra_off
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIC_IA_SPREL     ((UChar)1)
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIC_IA_BPREL     ((UChar)2)
201436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define CFIC_ARM_R13REL   ((UChar)3)
202436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define CFIC_ARM_R12REL   ((UChar)4)
203436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define CFIC_ARM_R11REL   ((UChar)5)
204436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define CFIC_ARM_R7REL    ((UChar)6)
205436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define CFIC_ARM64_SPREL  ((UChar)7)
206436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define CFIC_ARM64_X29REL ((UChar)8)
207436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define CFIC_EXPR         ((UChar)9)  /* all targets */
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIR_UNKNOWN      ((UChar)64)
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIR_SAME         ((UChar)65)
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIR_CFAREL       ((UChar)66)
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIR_MEMCFAREL    ((UChar)67)
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define CFIR_EXPR         ((UChar)68)
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGA_x86) || defined(VGA_amd64)
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr  base;
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt  len;
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar cfa_how; /* a CFIC_IA value */
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar ra_how;  /* a CFIR_ value */
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar sp_how;  /* a CFIR_ value */
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar bp_how;  /* a CFIR_ value */
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   cfa_off;
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   ra_off;
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   sp_off;
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   bp_off;
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiCfSI;
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGA_arm)
231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr  base;
234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt  len;
235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar cfa_how; /* a CFIC_ value */
236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar ra_how;  /* a CFIR_ value */
237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar r14_how; /* a CFIR_ value */
238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar r13_how; /* a CFIR_ value */
239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar r12_how; /* a CFIR_ value */
240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar r11_how; /* a CFIR_ value */
241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar r7_how;  /* a CFIR_ value */
242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   cfa_off;
243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   ra_off;
244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   r14_off;
245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   r13_off;
246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   r12_off;
247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   r11_off;
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   r7_off;
249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiCfSI;
251436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(VGA_arm64)
252436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef
253436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   struct {
254436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Addr  base;
255436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      UInt  len;
256436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      UChar cfa_how; /* a CFIC_ value */
257436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      UChar ra_how;  /* a CFIR_ value */
258436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      UChar sp_how;  /* a CFIR_ value */ /*dw31=SP*/
259436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      UChar x30_how; /* a CFIR_ value */ /*dw30=LR*/
260436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      UChar x29_how; /* a CFIR_ value */ /*dw29=FP*/
261436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Int   cfa_off;
262436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Int   ra_off;
263436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Int   sp_off;
264436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Int   x30_off;
265436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Int   x29_off;
266436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
267436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   DiCfSI;
268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGA_ppc32) || defined(VGA_ppc64)
269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Just have a struct with the common fields in, so that code that
270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   processes the common fields doesn't have to be ifdef'd against
271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VGP_/VGA_ symbols.  These are not used in any way on ppc32/64-linux
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   at the moment. */
273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr  base;
276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt  len;
277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar cfa_how; /* a CFIC_ value */
278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar ra_how;  /* a CFIR_ value */
279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   cfa_off;
280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int   ra_off;
281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiCfSI;
283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#elif defined(VGA_s390x)
284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef
285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   struct {
286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Addr  base;
287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UInt  len;
288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UChar cfa_how; /* a CFIC_ value */
289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UChar sp_how;  /* a CFIR_ value */
290b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UChar ra_how;  /* a CFIR_ value */
291b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UChar fp_how;  /* a CFIR_ value */
292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Int   cfa_off;
293b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Int   sp_off;
294b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Int   ra_off;
295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Int   fp_off;
296b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
297b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   DiCfSI;
298436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#elif defined(VGA_mips32) || defined(VGA_mips64)
299663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef
300663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   struct {
301663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Addr  base;
302663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      UInt  len;
303663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      UChar cfa_how; /* a CFIC_ value */
304663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      UChar ra_how;  /* a CFIR_ value */
305663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      UChar sp_how;  /* a CFIR_ value */
306663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      UChar fp_how;  /* a CFIR_ value */
307663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Int   cfa_off;
308663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Int   ra_off;
309663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Int   sp_off;
310663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Int   fp_off;
311663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
312663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   DiCfSI;
313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  error "Unknown arch"
315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   enum {
320436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Cunop_Abs=0x231,
321436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Cunop_Neg,
322436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Cunop_Not
323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
324436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   CfiUnop;
325436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
326436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovtypedef
327436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   enum {
328436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Cbinop_Add=0x321,
329436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Cbinop_Sub,
330436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Cbinop_And,
331436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Cbinop_Mul,
332436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Cbinop_Shl,
333436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Cbinop_Shr,
334436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Cbinop_Eq,
335436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Cbinop_Ge,
336436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Cbinop_Gt,
337436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Cbinop_Le,
338436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Cbinop_Lt,
339436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Cbinop_Ne
340436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   }
341436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   CfiBinop;
342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   enum {
345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Creg_IA_SP=0x213,
346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Creg_IA_BP,
347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Creg_IA_IP,
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Creg_ARM_R13,
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Creg_ARM_R12,
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Creg_ARM_R15,
351b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Creg_ARM_R14,
352436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Creg_ARM64_X30,
353663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Creg_S390_R14,
354663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Creg_MIPS_RA
355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   CfiReg;
357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   enum {
360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Cex_Undef=0x123,
361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Cex_Deref,
362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Cex_Const,
363436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      Cex_Unop,
364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Cex_Binop,
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Cex_CfiReg,
366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Cex_DwReg
367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   CfiExprTag;
369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      CfiExprTag tag;
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      union {
374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } Undef;
376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Int ixAddr;
378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } Deref;
379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            UWord con;
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } Const;
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
383436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            CfiUnop op;
384436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            Int ix;
385436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         } Unop;
386436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov         struct {
387436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov            CfiBinop op;
388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Int ixL;
389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Int ixR;
390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } Binop;
391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            CfiReg reg;
393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } CfiReg;
394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         struct {
395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            Int reg;
396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } DwReg;
397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Cex;
399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   CfiExpr;
401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Int ML_(CfiExpr_Undef) ( XArray* dst );
403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Int ML_(CfiExpr_Deref) ( XArray* dst, Int ixAddr );
404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Int ML_(CfiExpr_Const) ( XArray* dst, UWord con );
405436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern Int ML_(CfiExpr_Unop)  ( XArray* dst, CfiUnop op, Int ix );
406436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern Int ML_(CfiExpr_Binop) ( XArray* dst, CfiBinop op, Int ixL, Int ixR );
407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Int ML_(CfiExpr_CfiReg)( XArray* dst, CfiReg reg );
408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Int ML_(CfiExpr_DwReg) ( XArray* dst, Int reg );
409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ML_(ppCfiExpr)( XArray* src, Int ix );
411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------- FPO INFO (Windows PE) -------------- */
413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* for apps using Wine: MSVC++ PDB FramePointerOmitted: somewhat like
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   a primitive CFI */
416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct _FPO_DATA {  /* 16 bytes */
418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt   ulOffStart; /* offset of 1st byte of function code */
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt   cbProcSize; /* # bytes in function */
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt   cdwLocals;  /* # bytes/4 in locals */
421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UShort cdwParams;  /* # bytes/4 in params */
422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar  cbProlog;   /* # bytes in prolog */
423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar  cbRegs :3;  /* # regs saved */
424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar  fHasSEH:1;  /* Structured Exception Handling */
425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar  fUseBP :1;  /* EBP has been used */
426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar  reserved:1;
427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UChar  cbFrame:2;  /* frame type */
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   FPO_DATA;
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PDB_FRAME_FPO  0
432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PDB_FRAME_TRAP 1
433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PDB_FRAME_TSS  2
434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------- VARIABLES --------------------- */
436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr    aMin;
440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr    aMax;
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      XArray* /* of DiVariable */ vars;
442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiAddrRange;
444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
447436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      HChar* name;  /* in DebugInfo.strchunks */
448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UWord  typeR; /* a cuOff */
449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      GExpr* gexpr; /* on DebugInfo.gexprs list */
450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      GExpr* fbGX;  /* SHARED. */
451436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      HChar* fileName; /* where declared; may be NULL. in
452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          DebugInfo.strchunks */
453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int    lineNo;   /* where declared; may be zero. */
454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiVariable;
456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownWord
458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownML_(cmp_for_DiAddrRange_range) ( const void* keyV, const void* elemV );
459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------- DEBUGINFO --------------------- */
461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This is the top-level data type.  It's a structure which contains
463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   information pertaining to one mapped ELF object.  This type is
464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   exported only abstractly - in pub_tool_debuginfo.h. */
465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
466b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* First though, here's an auxiliary data structure.  It is only ever
467b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   used as part of a struct _DebugInfo.  We use it to record
468b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   observations about mappings and permission changes to the
469b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   associated file, so as to decide when to read debug info.  It's
470b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   essentially an ultra-trivial finite state machine which, when it
471b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   reaches an accept state, signals that we should now read debug info
472b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   from the object into the associated struct _DebugInfo.  The accept
473b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   state is arrived at when have_rx_map and have_rw_map both become
474b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   true.  The initial state is one in which we have no observations,
475b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   so have_rx_map and have_rw_map are both false.
476b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
477663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   This all started as a rather ad-hoc solution, but was further
478663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   expanded to handle weird object layouts, e.g. more than one rw
479663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   or rx mapping for one binary.
480b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
481b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   The normal sequence of events is one of
482b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
483b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   start  -->  r-x mapping  -->  rw- mapping  -->  accept
484b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   start  -->  rw- mapping  -->  r-x mapping  -->  accept
485b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
486b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   that is, take the first r-x and rw- mapping we see, and we're done.
487b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
488b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   On MacOSX 10.7, 32-bit, there appears to be a new variant:
489b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
490b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   start  -->  r-- mapping  -->  rw- mapping
491b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov          -->  upgrade r-- mapping to r-x mapping  -->  accept
492b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
493b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   where the upgrade is done by a call to vm_protect.  Hence we
494b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   need to also track this possibility.
495b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/
496663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
497663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstruct _DebugInfoMapping
498b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
499663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Addr  avma; /* these fields record the file offset, length */
500663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   SizeT size; /* and map address of each mapping             */
501663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   OffT  foff;
502663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Bool  rx, rw, ro;  /* memory access flags for this mapping */
503663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng};
504b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
505663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengstruct _DebugInfoFSM
506663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{
507436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   HChar*  filename;  /* in mallocville (VG_AR_DINFO)               */
508663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   XArray* maps;      /* XArray of _DebugInfoMapping structs        */
509b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Bool  have_rx_map; /* did we see a r?x mapping yet for the file? */
510b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Bool  have_rw_map; /* did we see a rw? mapping yet for the file? */
511b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Bool  have_ro_map; /* did we see a r-- mapping yet for the file? */
512b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov};
513b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
514b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
515b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* To do with the string table in struct _DebugInfo (::strchunks) */
516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SEGINFO_STRCHUNKSIZE (64*1024)
517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
518b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
519b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* We may encounter more than one .eh_frame section in an object --
520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   unusual but apparently allowed by ELF.  See
521b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   http://sourceware.org/bugzilla/show_bug.cgi?id=12675
522b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/
523b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define N_EHFRAME_SECTS 2
524b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
526b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* So, the main structure for holding debug info for one object. */
527b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct _DebugInfo {
529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Admin stuff */
531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct _DebugInfo* next;   /* list of DebugInfos */
533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool               mark;   /* marked for deletion? */
534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* An abstract handle, which can be used by entities outside of
536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      m_debuginfo to (in an abstract datatype sense) refer to this
537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct _DebugInfo.  A .handle of zero is invalid; valid handles
538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      are 1 and above.  The same handle is never issued twice (in any
539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      given run of Valgrind), so a handle becomes invalid when the
540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      associated struct _DebugInfo is discarded, and remains invalid
541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      forever thereafter.  The .handle field is set as soon as this
542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      structure is allocated. */
543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ULong handle;
544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Used for debugging only - indicate what stuff to dump whilst
546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      reading stuff into the seginfo.  Are computed as early in the
547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lifetime of the DebugInfo as possible -- at the point when it is
548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      created.  Use these when deciding what to spew out; do not use
549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the global VG_(clo_blah) flags. */
550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool trace_symtab; /* symbols, our style */
552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool trace_cfi;    /* dwarf frame unwind, our style */
553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool ddump_syms;   /* mimic /usr/bin/readelf --syms */
554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool ddump_line;   /* mimic /usr/bin/readelf --debug-dump=line */
555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool ddump_frames; /* mimic /usr/bin/readelf --debug-dump=frames */
556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
557b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* The "decide when it is time to read debuginfo" state machine.
558b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      This structure must get filled in before we can start reading
559b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      anything from the ELF/MachO file.  This structure is filled in
560b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      by VG_(di_notify_mmap) and its immediate helpers. */
561b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   struct _DebugInfoFSM fsm;
562b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
563b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Once the ::fsm has reached an accept state -- typically, when
564b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      both a rw? and r?x mapping for .filename have been observed --
565b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      we can go on to read the symbol tables and debug info.
566b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      .have_dinfo changes from False to True when the debug info has
567b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      been completely read in and postprocessed (canonicalised) and is
568b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      now suitable for querying. */
569b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* If have_dinfo is False, then all fields below this point are
570b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      invalid and should not be consulted. */
571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool  have_dinfo; /* initially False */
572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* All the rest of the fields in this structure are filled in once
574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      we have committed to reading the symbols and debug info (that
575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      is, at the point where .have_dinfo is set to True). */
576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
577663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* The file's soname. */
578436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   HChar* soname;
579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Description of some important mapped segments.  The presence or
581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      absence of the mapping is denoted by the _present field, since
582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      in some obscure circumstances (to do with data/sdata/bss) it is
583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      possible for the mapping to be present but have zero size.
584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Certainly text_ is mandatory on all platforms; not sure about
585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the rest though.
586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      --------------------------------------------------------
588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Comment_on_IMPORTANT_CFSI_REPRESENTATIONAL_INVARIANTS: we require that
590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
591663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      either (size of all rx maps == 0 && cfsi == NULL) (the degenerate case)
592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      or the normal case, which is the AND of the following:
594663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      (0) size of at least one rx mapping > 0
595663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      (1) no two DebugInfos with some rx mapping of size > 0
596663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          have overlapping rx mappings
597663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      (2) [cfsi_minavma,cfsi_maxavma] does not extend beyond
598663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          [avma,+size) of one rx mapping; that is, the former
599663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          is a subrange or equal to the latter.
600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (3) all DiCfSI in the cfsi array all have ranges that fall within
601663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng          [avma,+size) of that rx mapping.
602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (4) all DiCfSI in the cfsi array are non-overlapping
603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      The cumulative effect of these restrictions is to ensure that
605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      all the DiCfSI records in the entire system are non overlapping.
606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Hence any address falls into either exactly one DiCfSI record,
607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      or none.  Hence it is safe to cache the results of searches for
608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      DiCfSI records.  This is the whole point of these restrictions.
609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      The caching of DiCfSI searches is done in VG_(use_CF_info).  The
610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cache is flushed after any change to debugInfo_list.  DiCfSI
611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      searches are cached because they are central to stack unwinding
612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      on amd64-linux.
613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Where are these invariants imposed and checked?
615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      They are checked after a successful read of debuginfo into
617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a DebugInfo*, in check_CFSI_related_invariants.
618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (1) is not really imposed anywhere.  We simply assume that the
620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      kernel will not map the text segments from two different objects
621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      into the same space.  Sounds reasonable.
622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (2) follows from (4) and (3).  It is ensured by canonicaliseCFI.
624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (3) is ensured by ML_(addDiCfSI).
625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (4) is ensured by canonicaliseCFI.
626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      --------------------------------------------------------
628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Comment_on_DEBUG_SVMA_and_DEBUG_BIAS_fields:
630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      The _debug_{svma,bias} fields were added as part of a fix to
632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      #185816.  The problem encompassed in that bug report was that it
633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      wasn't correct to use apply the bias values deduced for a
634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      primary object to its associated debuginfo object, because the
635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      debuginfo object (or the primary) could have been prelinked to a
636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      different SVMA.  Hence debuginfo and primary objects need to
637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      have their own biases.
638ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
639ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ------ JRS: (referring to r9329): ------
640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Let me see if I understand the workings correctly.  Initially
641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the _debug_ values are set to the same values as the "normal"
642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ones, as there's a bunch of bits of code like this (in
643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      readelf.c)
644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         di->text_svma = svma;
646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         ...
647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         di->text_bias = rx_bias;
648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         di->text_debug_svma = svma;
649ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         di->text_debug_bias = rx_bias;
650ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
651ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      If a debuginfo object subsequently shows up then the
652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      _debug_svma/bias are set for the debuginfo object.  Result is
653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      that if there's no debuginfo object then the values are the same
654ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      as the primary-object values, and if there is a debuginfo object
655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      then they will (or at least may) be different.
656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Then when we need to actually bias something, we'll have to
658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      decide whether to use the primary bias or the debuginfo bias.
659ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      And the strategy is to use the primary bias for ELF symbols but
660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the debuginfo bias for anything pulled out of Dwarf.
661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ------ THH: ------
663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Correct - the debug_svma and bias values apply to any address
664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      read from the debug data regardless of where that debug data is
665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      stored and the other values are used for addresses from other
666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      places (primarily the symbol table).
667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ------ JRS: ------
669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Ok; so this was my only area of concern.  Are there any
670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      corner-case scenarios where this wouldn't be right?  It sounds
671ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      like we're assuming the ELF symbols come from the primary object
672ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      and, if there is a debug object, then all the Dwarf comes from
673ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      there.  But what if (eg) both symbols and Dwarf come from the
674ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      debug object?  Is that even possible or allowable?
675ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
676ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      ------ THH: ------
677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      You may have a point...
678ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
679ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      The current logic is to try and take any one set of data from
680ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      either the base object or the debug object. There are four sets
681ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      of data we consider:
682ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
683ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         - Symbol Table
684ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         - Stabs
685ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         - DWARF1
686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         - DWARF2
687ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
688ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      If we see the primary section for a given set in the base object
689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      then we ignore all sections relating to that set in the debug
690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      object.
691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Now in principle if we saw a secondary section (like debug_line
693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      say) in the base object, but not the main section (debug_info in
694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      this case) then we would take debug_info from the debug object
695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      but would use the debug_line from the base object unless we saw
696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      a replacement copy in the debug object. That's probably unlikely
697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      however.
698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      A bigger issue might be, as you say, the symbol table as we will
700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      pick that up from the debug object if it isn't in the base. The
701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dynamic symbol table will always have to be in the base object
702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      though so we will have to be careful when processing symbols to
703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      know which table we are reading in that case.
704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      What we probably need to do is tell read_elf_symtab which object
706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      the symbols it is being asked to read came from.
707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      (A followup patch to deal with this was committed in r9469).
709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   */
710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .text */
711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool     text_present;
712ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     text_avma;
713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     text_svma;
714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT    text_size;
715ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT text_bias;
716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     text_debug_svma;
717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT text_debug_bias;
718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .data */
719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool     data_present;
720ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     data_svma;
721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     data_avma;
722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT    data_size;
723ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT data_bias;
724ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     data_debug_svma;
725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT data_debug_bias;
726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .sdata */
727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool     sdata_present;
728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     sdata_svma;
729ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     sdata_avma;
730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT    sdata_size;
731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT sdata_bias;
732ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     sdata_debug_svma;
733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT sdata_debug_bias;
734ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .rodata */
735ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool     rodata_present;
736ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     rodata_svma;
737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     rodata_avma;
738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT    rodata_size;
739ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT rodata_bias;
740ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     rodata_debug_svma;
741ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT rodata_debug_bias;
742ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .bss */
743ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool     bss_present;
744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     bss_svma;
745ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     bss_avma;
746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT    bss_size;
747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT bss_bias;
748ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     bss_debug_svma;
749ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT bss_debug_bias;
750ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .sbss */
751ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool     sbss_present;
752ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     sbss_svma;
753ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     sbss_avma;
754ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT    sbss_size;
755ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT sbss_bias;
756ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr     sbss_debug_svma;
757ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PtrdiffT sbss_debug_bias;
758ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .plt */
759ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool   plt_present;
760ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr	  plt_avma;
761ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT  plt_size;
762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .got */
763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool   got_present;
764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr   got_avma;
765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT  got_size;
766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .got.plt */
767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool   gotplt_present;
768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr   gotplt_avma;
769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT  gotplt_size;
770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* .opd -- needed on ppc64-linux for finding symbols */
771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool   opd_present;
772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr   opd_avma;
773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SizeT  opd_size;
774b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* .ehframe -- needed on amd64-linux for stack unwinding.  We might
775b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      see more than one, hence the arrays. */
776b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UInt   n_ehframe;  /* 0 .. N_EHFRAME_SECTS */
777b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Addr   ehframe_avma[N_EHFRAME_SECTS];
778b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   SizeT  ehframe_size[N_EHFRAME_SECTS];
779ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Sorted tables of stuff we snarfed from the file.  This is the
781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      eventual product of reading the debug info.  All this stuff
782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      lives in VG_AR_DINFO. */
783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* An expandable array of symbols. */
785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiSym*  symtab;
786ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord   symtab_used;
787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord   symtab_size;
788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* An expandable array of locations. */
789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiLoc*  loctab;
790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord   loctab_used;
791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord   loctab_size;
792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* An expandable array of CFI summary info records.  Also includes
793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      summary address bounds, showing the min and max address covered
794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      by any of the records, as an aid to fast searching.  And, if the
795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      records require any expression nodes, they are stored in
796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      cfsi_exprs. */
797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DiCfSI* cfsi;
798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord   cfsi_used;
799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord   cfsi_size;
800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr    cfsi_minavma;
801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr    cfsi_maxavma;
802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   XArray* cfsi_exprs; /* XArray of CfiExpr */
803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Optimized code under Wine x86: MSVC++ PDB FramePointerOmitted
805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      data.  Non-expandable array, hence .size == .used. */
806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   FPO_DATA* fpo;
807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UWord     fpo_size;
808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr      fpo_minavma;
809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr      fpo_maxavma;
810663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Addr      fpo_base_avma;
811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Expandable arrays of characters -- the string table.  Pointers
813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      into this are stable (the arrays are not reallocated). */
814ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct strchunk {
815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt   strtab_used;
816ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      struct strchunk* next;
817436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov      HChar  strtab[SEGINFO_STRCHUNKSIZE];
818ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } *strchunks;
819ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
820ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Variable scope information, as harvested from Dwarf3 files.
821ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      In short it's an
823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         array of (array of PC address ranges and variables)
825ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      The outer array indexes over scopes, with Entry 0 containing
827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      information on variables which exist for any value of the program
828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      counter (PC) -- that is, the outermost scope.  Entries 1, 2, 3,
829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      etc contain information on increasinly deeply nested variables.
830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Each inner array is an array of (an address range, and a set
832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      of variables that are in scope over that address range).
833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      The address ranges may not overlap.
835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Since Entry 0 in the outer array holds information on variables
837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      that exist for any value of the PC (that is, global vars), it
838ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      follows that Entry 0's inner array can only have one address
839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      range pair, one that covers the entire address space.
840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   */
841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   XArray* /* of OSet of DiAddrRange */varinfo;
842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* These are arrays of the relevant typed objects, held here
844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      partially for the purposes of visiting each object exactly once
845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      when we need to delete them. */
846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* An array of TyEnts.  These are needed to make sense of any types
848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      in the .varinfo.  Also, when deleting this DebugInfo, we must
849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      first traverse this array and throw away malloc'd stuff hanging
850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      off it -- by calling ML_(TyEnt__make_EMPTY) on each entry. */
851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   XArray* /* of TyEnt */ admin_tyents;
852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
853ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* An array of guarded DWARF3 expressions. */
854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   XArray* admin_gexprs;
855663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
856663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* Cached last rx mapping matched and returned by ML_(find_rx_mapping).
857663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      This helps performance a lot during ML_(addLineInfo) etc., which can
858663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      easily be invoked hundreds of thousands of times. */
859663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   struct _DebugInfoMapping* last_rx_map;
860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown};
861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------- functions --------------------- */
863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------ Adding ------ */
865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
866b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Add a symbol to si's symbol table.  The contents of 'sym' are
867b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   copied.  It is assumed (and checked) that 'sym' only contains one
868b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   name, so there is no auxiliary ::sec_names vector to duplicate.
869b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   IOW, the copy is a shallow copy, and there are assertions in place
870b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   to ensure that's OK. */
871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ML_(addSym) ( struct _DebugInfo* di, DiSym* sym );
872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a line-number record to a DebugInfo. */
874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern
875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid ML_(addLineInfo) ( struct _DebugInfo* di,
876436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                        const HChar* filename,
877436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                        const HChar* dirname,  /* NULL is allowable */
878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                        Addr this, Addr next, Int lineno, Int entry);
879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a CFI summary record.  The supplied DiCfSI is copied. */
881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ML_(addDiCfSI) ( struct _DebugInfo* di, DiCfSI* cfsi );
882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
883ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a string to the string table of a DebugInfo.  If len==-1,
884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ML_(addStr) will itself measure the length of the string. */
885436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern HChar* ML_(addStr) ( struct _DebugInfo* di, const HChar* str, Int len );
886436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov
887436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* Add a string to the string table of a DebugInfo, by copying the
888436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   string from the given DiCursor.  Measures the length of the string
889436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   itself. */
890436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovextern HChar* ML_(addStrFromCursor)( struct _DebugInfo* di, DiCursor c );
891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ML_(addVar)( struct _DebugInfo* di,
893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         Int    level,
894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         Addr   aMin,
895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         Addr   aMax,
896436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                         HChar* name,
897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         UWord  typeR, /* a cuOff */
898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         GExpr* gexpr,
899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         GExpr* fbGX, /* SHARED. */
900436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov                         HChar* fileName, /* where decl'd - may be NULL */
901ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         Int    lineNo, /* where decl'd - may be zero */
902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         Bool   show );
903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Canonicalise the tables held by 'di', in preparation for use.  Call
905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   this after finishing adding entries to these tables. */
906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ML_(canonicaliseTables) ( struct _DebugInfo* di );
907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Canonicalise the call-frame-info table held by 'di', in preparation
909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   for use. This is called by ML_(canonicaliseTables) but can also be
910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   called on it's own to sort just this table. */
911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ML_(canonicaliseCFI) ( struct _DebugInfo* di );
912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------ Searching ------ */
914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Find a symbol-table index containing the specified pointer, or -1
916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if not found.  Binary search.  */
917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Word ML_(search_one_symtab) ( struct _DebugInfo* di, Addr ptr,
918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                     Bool match_anywhere_in_sym,
919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                     Bool findText );
920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
921ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Find a location-table index containing the specified pointer, or -1
922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if not found.  Binary search.  */
923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Word ML_(search_one_loctab) ( struct _DebugInfo* di, Addr ptr );
924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Find a CFI-table index containing the specified pointer, or -1 if
926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   not found.  Binary search.  */
927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Word ML_(search_one_cfitab) ( struct _DebugInfo* di, Addr ptr );
928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Find a FPO-table index containing the specified pointer, or -1
930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if not found.  Binary search.  */
931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern Word ML_(search_one_fpotab) ( struct _DebugInfo* di, Addr ptr );
932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
933663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Helper function for the most often needed searching for an rx
934663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   mapping containing the specified address range.  The range must
935663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   fall entirely within the mapping to be considered to be within it.
936663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Asserts if lo > hi; caller must ensure this doesn't happen. */
937663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengextern struct _DebugInfoMapping* ML_(find_rx_mapping) ( struct _DebugInfo* di,
938663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                                                        Addr lo, Addr hi );
939663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
940ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ------ Misc ------ */
941ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
942ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Show a non-fatal debug info reading error.  Use vg_panic if
943ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   terminal.  'serious' errors are always shown, not 'serious' ones
944ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   are shown only at verbosity level 2 and above. */
945ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern
946436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid ML_(symerr) ( struct _DebugInfo* di, Bool serious, const HChar* msg );
947ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
948ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print a symbol. */
949ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ML_(ppSym) ( Int idx, DiSym* sym );
950ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
951ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Print a call-frame-info summary. */
952ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern void ML_(ppDiCfSI) ( XArray* /* of CfiExpr */ exprs, DiCfSI* si );
953ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
954ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
955436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#define TRACE_SYMTAB_ENABLED (di->trace_symtab)
956ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define TRACE_SYMTAB(format, args...) \
957436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov   if (TRACE_SYMTAB_ENABLED) { VG_(printf)(format, ## args); }
958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif /* ndef __PRIV_STORAGE_H */
961ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end                                                          ---*/
964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
965