15d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* -*- mode: C; c-basic-offset: 3; -*- */
2ea27e4627518665dd6c81213c0ba1f7ff0218e1anjn
34bbdc9756d8750b77759b31da2dbebffaf957b5enjn/*--------------------------------------------------------------------*/
4fba428cd266b8a39db641c5fd9523daa8939bed0tom/*--- Read DWARF1/2/3/4 debug info.                    readdwarf.c ---*/
54bbdc9756d8750b77759b31da2dbebffaf957b5enjn/*--------------------------------------------------------------------*/
64bbdc9756d8750b77759b31da2dbebffaf957b5enjn
74bbdc9756d8750b77759b31da2dbebffaf957b5enjn/*
8b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn   This file is part of Valgrind, a dynamic binary instrumentation
9b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn   framework.
104bbdc9756d8750b77759b31da2dbebffaf957b5enjn
11b3a1e4bffbdbbf38304f216af405009868f43628sewardj   Copyright (C) 2000-2015 Julian Seward
124bbdc9756d8750b77759b31da2dbebffaf957b5enjn      jseward@acm.org
134bbdc9756d8750b77759b31da2dbebffaf957b5enjn
144bbdc9756d8750b77759b31da2dbebffaf957b5enjn   This program is free software; you can redistribute it and/or
154bbdc9756d8750b77759b31da2dbebffaf957b5enjn   modify it under the terms of the GNU General Public License as
164bbdc9756d8750b77759b31da2dbebffaf957b5enjn   published by the Free Software Foundation; either version 2 of the
174bbdc9756d8750b77759b31da2dbebffaf957b5enjn   License, or (at your option) any later version.
184bbdc9756d8750b77759b31da2dbebffaf957b5enjn
194bbdc9756d8750b77759b31da2dbebffaf957b5enjn   This program is distributed in the hope that it will be useful, but
204bbdc9756d8750b77759b31da2dbebffaf957b5enjn   WITHOUT ANY WARRANTY; without even the implied warranty of
214bbdc9756d8750b77759b31da2dbebffaf957b5enjn   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
224bbdc9756d8750b77759b31da2dbebffaf957b5enjn   General Public License for more details.
234bbdc9756d8750b77759b31da2dbebffaf957b5enjn
244bbdc9756d8750b77759b31da2dbebffaf957b5enjn   You should have received a copy of the GNU General Public License
254bbdc9756d8750b77759b31da2dbebffaf957b5enjn   along with this program; if not, write to the Free Software
264bbdc9756d8750b77759b31da2dbebffaf957b5enjn   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
274bbdc9756d8750b77759b31da2dbebffaf957b5enjn   02111-1307, USA.
284bbdc9756d8750b77759b31da2dbebffaf957b5enjn
294bbdc9756d8750b77759b31da2dbebffaf957b5enjn   The GNU General Public License is contained in the file COPYING.
304bbdc9756d8750b77759b31da2dbebffaf957b5enjn*/
318b68b64759254d514d98328c496cbd88cde4c9a5njn
328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris)
33cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
34c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_core_basics.h"
35588658b13b5ad77672f323d48fe9da0ca60b0bcbtom#include "pub_core_debuginfo.h"
3697405b2d134b52880d6dbec3eb2929e2002c2542njn#include "pub_core_libcbase.h"
37132bfccd21960e462352175f8553a5bdce8a210cnjn#include "pub_core_libcassert.h"
3836a20fa5f779a0a6fb7b4a90dcaa6376481f1faanjn#include "pub_core_libcprint.h"
392024234c590f408994b373abfb00bc2cd2a90c48njn#include "pub_core_options.h"
4072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj#include "pub_core_xarray.h"
413c9cf3442185b5891e15450d6e3058aeff6796fetom#include "pub_core_tooliface.h"    /* VG_(needs) */
42b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_misc.h"             /* dinfo_zalloc/free/strdup */
435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj#include "priv_image.h"
44b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_d3basics.h"
45b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#include "priv_tytypes.h"
46eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_storage.h"
47eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj#include "priv_readdwarf.h"        /* self */
48f4c50164b9a89e3421cd6650f7187bd46b936cbdnjn
49cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
50eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/
51eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*---                                                      ---*/
52eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- Read line number and CFI info from DWARF1, DWARF2    ---*/
53eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*--- and to some extent DWARF3 sections.                  ---*/
54eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*---                                                      ---*/
55eadcd86d1b0f59efed44c162ef4378ccfb528290sewardj/*------------------------------------------------------------*/
56c613dff23c0f2e971c368fd2b2135df5d3e6b12dsewardj
5759e1f3c79e870a978d24add86db6d8c5450c8b63philippe/* The below "safe_*ix" functions allow to resist to malformed dwarf info:
5859e1f3c79e870a978d24add86db6d8c5450c8b63philippe   if dwarf info contains wrong file or dirname indexes, these are (silently!)
5959e1f3c79e870a978d24add86db6d8c5450c8b63philippe   ignored. */
6059e1f3c79e870a978d24add86db6d8c5450c8b63philippe
6159e1f3c79e870a978d24add86db6d8c5450c8b63philippe/* if xa_ix is a valid index in fndn_ix_xa,
6259e1f3c79e870a978d24add86db6d8c5450c8b63philippe    return the element (i.e. the UInt indexing in fndnpool).
6359e1f3c79e870a978d24add86db6d8c5450c8b63philippe   If xa_ix is invalid, return 0 (i.e. the "null" element in fndnpool). */
6459e1f3c79e870a978d24add86db6d8c5450c8b63philippestatic UInt safe_fndn_ix (XArray* fndn_ix_xa, Int xa_ix)
65c613dff23c0f2e971c368fd2b2135df5d3e6b12dsewardj{
6659e1f3c79e870a978d24add86db6d8c5450c8b63philippe   if (xa_ix < 0) return 0;
6759e1f3c79e870a978d24add86db6d8c5450c8b63philippe   if (xa_ix >= VG_(sizeXA) (fndn_ix_xa)) return 0;
6859e1f3c79e870a978d24add86db6d8c5450c8b63philippe   return *(UInt*)VG_(indexXA) ( fndn_ix_xa, xa_ix );
69c613dff23c0f2e971c368fd2b2135df5d3e6b12dsewardj}
70c613dff23c0f2e971c368fd2b2135df5d3e6b12dsewardj
7159e1f3c79e870a978d24add86db6d8c5450c8b63philippe/* if xa_ix is a valid index in dirname_xa,
7259e1f3c79e870a978d24add86db6d8c5450c8b63philippe    return the element (i.e. the HChar*).
7359e1f3c79e870a978d24add86db6d8c5450c8b63philippe   If xa_ix is invalid, return NULL. */
741ef70c6f00ab1b50d1936f77037e9923d8ed8c59florianstatic const HChar* safe_dirname_ix (XArray* dirname_xa, Int xa_ix)
75c613dff23c0f2e971c368fd2b2135df5d3e6b12dsewardj{
7659e1f3c79e870a978d24add86db6d8c5450c8b63philippe   if (xa_ix < 0) return NULL;
7759e1f3c79e870a978d24add86db6d8c5450c8b63philippe   if (xa_ix >= VG_(sizeXA) (dirname_xa)) return NULL;
7859e1f3c79e870a978d24add86db6d8c5450c8b63philippe   return *(HChar**)VG_(indexXA) ( dirname_xa, xa_ix );
79c613dff23c0f2e971c368fd2b2135df5d3e6b12dsewardj}
80c613dff23c0f2e971c368fd2b2135df5d3e6b12dsewardj
81c613dff23c0f2e971c368fd2b2135df5d3e6b12dsewardj/*------------------------------------------------------------*/
82c613dff23c0f2e971c368fd2b2135df5d3e6b12dsewardj/*--- Read DWARF2 format line number info.                 ---*/
83c613dff23c0f2e971c368fd2b2135df5d3e6b12dsewardj/*------------------------------------------------------------*/
84c613dff23c0f2e971c368fd2b2135df5d3e6b12dsewardj
851162491ad6e90572f6417b2dae767ee5694d1e94sewardj/* Structure holding info extracted from the a .debug_line
861162491ad6e90572f6417b2dae767ee5694d1e94sewardj   section.  */
87cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgftypedef struct
88cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf{
891162491ad6e90572f6417b2dae767ee5694d1e94sewardj  ULong  li_length;
90cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  UShort li_version;
911162491ad6e90572f6417b2dae767ee5694d1e94sewardj  ULong  li_header_length;
92cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  UChar  li_min_insn_length;
93fba428cd266b8a39db641c5fd9523daa8939bed0tom  UChar  li_max_ops_per_insn;
94cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  UChar  li_default_is_stmt;
95cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  Int    li_line_base;
96cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  UChar  li_line_range;
97cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  UChar  li_opcode_base;
98cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf}
991162491ad6e90572f6417b2dae767ee5694d1e94sewardjDebugLineInfo;
100cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
101022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj/* Structure holding additional infos found from a .debug_info
102022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj * compilation unit block */
103022bf2fa104dbad3451c9b95265e2979a4d5faafsewardjtypedef struct
104022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj{
105022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj  /* Feel free to add more members here if you need ! */
1065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj  DiCursor compdir;  /* Compilation directory - points to .debug_info */
1075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj  DiCursor name;     /* Main file name - points to .debug_info */
1085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj  ULong    stmt_list; /* Offset in .debug_line */
1095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj  Bool     dw64;      /* 64-bit Dwarf? */
110022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj}
111022bf2fa104dbad3451c9b95265e2979a4d5faafsewardjUnitInfo;
112022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
113cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf/* Line number opcodes.  */
114cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgfenum dwarf_line_number_ops
115cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  {
116cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf    DW_LNS_extended_op = 0,
117cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf    DW_LNS_copy = 1,
118cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf    DW_LNS_advance_pc = 2,
119cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf    DW_LNS_advance_line = 3,
120cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf    DW_LNS_set_file = 4,
121cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf    DW_LNS_set_column = 5,
122cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf    DW_LNS_negate_stmt = 6,
123cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf    DW_LNS_set_basic_block = 7,
124cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf    DW_LNS_const_add_pc = 8,
125cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf    DW_LNS_fixed_advance_pc = 9,
126cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf    /* DWARF 3.  */
127cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf    DW_LNS_set_prologue_end = 10,
128cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf    DW_LNS_set_epilogue_begin = 11,
129cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf    DW_LNS_set_isa = 12
130cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  };
131cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
132cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf/* Line number extended opcodes.  */
133cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgfenum dwarf_line_number_x_ops
134cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  {
135cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf    DW_LNE_end_sequence = 1,
136cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf    DW_LNE_set_address = 2,
137fba428cd266b8a39db641c5fd9523daa8939bed0tom    DW_LNE_define_file = 3,
138fba428cd266b8a39db641c5fd9523daa8939bed0tom    DW_LNE_set_discriminator = 4
139cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  };
140cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
1413646a495f974e4aacf329e7539a0d584962ff6f6sewardjtypedef struct
142cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf{
143cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  /* Information for the last statement boundary.
144cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf   * Needed to calculate statement lengths. */
145cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  Addr  last_address;
146cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  UInt  last_file;
147cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  UInt  last_line;
148cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
149cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  Addr  address;
150cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  UInt  file;
151cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  UInt  line;
152cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  UInt  column;
153cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  Int   is_stmt;
154cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf  Int   basic_block;
155fba428cd266b8a39db641c5fd9523daa8939bed0tom  UChar end_sequence;
1563646a495f974e4aacf329e7539a0d584962ff6f6sewardj} LineSMR;
157cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
158cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
159b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* FIXME: duplicated in readdwarf3.c */
1605d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Read a 'leb128' and advance *data accordingly. */
1615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic ULong step_leb128 ( DiCursor* data, Int sign )
162cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf{
1635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   ULong  result = 0;
1645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   Int    shift = 0;
1655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UChar  byte;
16672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
1675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   vg_assert(sign == 0 || sign == 1);
168cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
1695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   do {
1705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      byte = ML_(cur_step_UChar)(data);
171c4217cd6b977a21385a2f5f0559318392a73dc1bsewardj      result |= ((ULong)(byte & 0x7f)) << shift;
172cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf      shift += 7;
1735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   }
1745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   while (byte & 0x80);
175cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
1765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (sign && (shift < 64) && (byte & 0x40))
1775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      result |= -(1ULL << shift);
178cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
1795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return result;
180cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf}
181cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
182b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* FIXME: duplicated in readdwarf3.c */
1835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic ULong step_leb128U( DiCursor* data ) {
1845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return step_leb128( data, 0 );
185022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj}
186022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
187b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* FIXME: duplicated in readdwarf3.c */
1885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic Long step_leb128S( DiCursor* data ) {
1895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return step_leb128( data, 1 );
190022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj}
191022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
1921162491ad6e90572f6417b2dae767ee5694d1e94sewardj/* Read what the DWARF3 spec calls an "initial length field".  This
1931162491ad6e90572f6417b2dae767ee5694d1e94sewardj   uses up either 4 or 12 bytes of the input and produces a 32-bit or
1941162491ad6e90572f6417b2dae767ee5694d1e94sewardj   64-bit number respectively.
1951162491ad6e90572f6417b2dae767ee5694d1e94sewardj
1961162491ad6e90572f6417b2dae767ee5694d1e94sewardj   Read 32-bit value from p.  If it is 0xFFFFFFFF, instead read a
1971162491ad6e90572f6417b2dae767ee5694d1e94sewardj   64-bit bit value from p+4.  This is used in 64-bit dwarf to encode
1985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   some table lengths.  Advance the cursor (p) accordingly.
199c4217cd6b977a21385a2f5f0559318392a73dc1bsewardj
200c4217cd6b977a21385a2f5f0559318392a73dc1bsewardj   XXX this is a hack: the endianness of the initial length field is
201c4217cd6b977a21385a2f5f0559318392a73dc1bsewardj   specified by the DWARF we're reading.  This happens to work only
202c4217cd6b977a21385a2f5f0559318392a73dc1bsewardj   because we don't do cross-arch jitting, hence this code runs on a
203c4217cd6b977a21385a2f5f0559318392a73dc1bsewardj   platform of the same endianness as the DWARF it is reading.  Same
204c4217cd6b977a21385a2f5f0559318392a73dc1bsewardj   applies for initial lengths for CIE/FDEs and probably in zillions
205c4217cd6b977a21385a2f5f0559318392a73dc1bsewardj   of other places -- to be precise, exactly the places where
206c4217cd6b977a21385a2f5f0559318392a73dc1bsewardj   binutils/dwarf.c calls byte_get().
207c4217cd6b977a21385a2f5f0559318392a73dc1bsewardj*/
2085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic
2095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjULong step_initial_length_field ( DiCursor* p_img, /*OUT*/Bool* is64 )
2101162491ad6e90572f6417b2dae767ee5694d1e94sewardj{
2115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UInt w32 = ML_(cur_step_UInt)(p_img);
2121162491ad6e90572f6417b2dae767ee5694d1e94sewardj   if (w32 == 0xFFFFFFFF) {
2131162491ad6e90572f6417b2dae767ee5694d1e94sewardj      *is64 = True;
2145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      return ML_(cur_step_ULong)(p_img);
2151162491ad6e90572f6417b2dae767ee5694d1e94sewardj   } else {
2161162491ad6e90572f6417b2dae767ee5694d1e94sewardj      *is64 = False;
2171162491ad6e90572f6417b2dae767ee5694d1e94sewardj      return (ULong)w32;
2181162491ad6e90572f6417b2dae767ee5694d1e94sewardj   }
2191162491ad6e90572f6417b2dae767ee5694d1e94sewardj}
2201162491ad6e90572f6417b2dae767ee5694d1e94sewardj
2215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic
2225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjULong read_initial_length_field ( DiCursor p_img, /*OUT*/Bool* is64 )
2235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj{
2245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   /* Something of a roundabout approach .. the modification to p_img
2255d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      is abandoned. */
2265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return step_initial_length_field( &p_img, is64 );
2275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj}
2285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
229022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
2303646a495f974e4aacf329e7539a0d584962ff6f6sewardjstatic LineSMR state_machine_regs;
231cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
232cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgfstatic
233cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgfvoid reset_state_machine ( Int is_stmt )
234cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf{
235a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart   if (0) VG_(printf)("smr.a := %p (reset)\n", NULL );
236022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   state_machine_regs.last_address = 0;
237022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   state_machine_regs.last_file = 1;
238022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   state_machine_regs.last_line = 1;
239022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   state_machine_regs.address = 0;
240022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   state_machine_regs.file = 1;
241022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   state_machine_regs.line = 1;
242022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   state_machine_regs.column = 0;
243022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   state_machine_regs.is_stmt = is_stmt;
244022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   state_machine_regs.basic_block = 0;
245022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   state_machine_regs.end_sequence = 0;
246cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf}
247cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
248022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj////////////////////////////////////////////////////////////////////
249022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj////////////////////////////////////////////////////////////////////
250c613dff23c0f2e971c368fd2b2135df5d3e6b12dsewardj
2515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj/* Handled an extended line op starting at *data, and advance *data
2525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   accordingly. */
253cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgfstatic
2545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjvoid process_extended_line_op( struct _DebugInfo* di,
25559e1f3c79e870a978d24add86db6d8c5450c8b63philippe                               XArray* fndn_ix_xa,
2565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                               DiCursor* data, Int is_stmt)
257cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf{
2585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UInt len = step_leb128U(data);
259022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   if (len == 0) {
260cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf      VG_(message)(Vg_UserMsg,
2611ff57e6a7669ea9ccebd7cc8883e02b477e8597bsewardj                   "Warning: DWARF2 reader: "
262738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                   "Badly formed extended line op encountered\n");
2635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      return;
264022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   }
265cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
2665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UChar op_code = ML_(cur_step_UChar)(data);
267022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   if (0) VG_(printf)("dwarf2: ext OPC: %d\n", op_code);
268022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
269022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   switch (op_code) {
270022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      case DW_LNE_end_sequence:
271a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart         if (0) VG_(printf)("1001: si->o %#lx, smr.a %#lx\n",
272c6e5d76e9eea8625f385ff844545c688c91938daflorian                            (UWord)di->text_debug_bias,
273c6e5d76e9eea8625f385ff844545c688c91938daflorian                            state_machine_regs.address );
274022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         /* JRS: added for compliance with spec; is pointless due to
275022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            reset_state_machine below */
276022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         state_machine_regs.end_sequence = 1;
277022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
278022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         if (state_machine_regs.is_stmt) {
2791ff57e6a7669ea9ccebd7cc8883e02b477e8597bsewardj            if (state_machine_regs.last_address) {
2807eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardj               ML_(addLineInfo) (
28159e1f3c79e870a978d24add86db6d8c5450c8b63philippe                  di,
28259e1f3c79e870a978d24add86db6d8c5450c8b63philippe                  safe_fndn_ix (fndn_ix_xa,
28359e1f3c79e870a978d24add86db6d8c5450c8b63philippe                                state_machine_regs.last_file),
284402c9eed11b9b60c6e134d05db938e395466cf99tom                  di->text_debug_bias + state_machine_regs.last_address,
285402c9eed11b9b60c6e134d05db938e395466cf99tom                  di->text_debug_bias + state_machine_regs.address,
286022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj                  state_machine_regs.last_line, 0
287022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj               );
2881ff57e6a7669ea9ccebd7cc8883e02b477e8597bsewardj            }
289022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         }
290022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         reset_state_machine (is_stmt);
291b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_line)
2923646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  Extended opcode %d: End of Sequence\n\n",
2933646a495f974e4aacf329e7539a0d584962ff6f6sewardj                        (Int)op_code);
294022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         break;
295022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
2965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      case DW_LNE_set_address: {
2975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         Addr adr = ML_(cur_step_Addr)(data);
298022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         state_machine_regs.address = adr;
299b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_line)
3003646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  Extended opcode %d: set Address to 0x%lx\n",
3013646a495f974e4aacf329e7539a0d584962ff6f6sewardj                        (Int)op_code, (Addr)adr);
302022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         break;
3035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      }
304022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
3055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      case DW_LNE_define_file: {
3065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         HChar* name = ML_(cur_step_strdup)(data, "di.pelo.1");
30759e1f3c79e870a978d24add86db6d8c5450c8b63philippe         UInt fndn_ix = ML_(addFnDn) (di, name, NULL);
30859e1f3c79e870a978d24add86db6d8c5450c8b63philippe         VG_(addToXA) (fndn_ix_xa, &fndn_ix);
3095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ML_(dinfo_free)(name);
3105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         (void)step_leb128U(data); // ignored: dir index
3115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         (void)step_leb128U(data); // ignored: mod time
3125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         (void)step_leb128U(data); // ignored: file size
313b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_line)
3143646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  DWARF2-line: set_address\n");
315022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         break;
3165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      }
317cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
318fba428cd266b8a39db641c5fd9523daa8939bed0tom      case DW_LNE_set_discriminator:
3195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         (void)step_leb128U(data); // ignored: new 'discriminator' value
320fba428cd266b8a39db641c5fd9523daa8939bed0tom         break;
321fba428cd266b8a39db641c5fd9523daa8939bed0tom
322022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      default:
323b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_line)
3243646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("process_extended_line_op:default\n");
325022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         break;
326022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   }
327022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj}
328cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
329022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj////////////////////////////////////////////////////////////////////
330022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj////////////////////////////////////////////////////////////////////
331022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
332022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj/* read a .debug_line section block for a compilation unit
333022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj *
334022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj * Input:   - theBlock must point to the start of the block
335022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj *            for the given compilation unit
336022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj *          - ui contains additional info like the compilation dir
337022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj *            for this unit
338022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj *
339022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj * Output: - si debug info structures get updated
340022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj */
341022bf2fa104dbad3451c9b95265e2979a4d5faafsewardjstatic
342b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid read_dwarf2_lineblock ( struct _DebugInfo* di,
343518850bf0da07ed3e2244e307268ae0fd80e93a8florian                             const UnitInfo* ui,
3445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             DiCursor  theBlock, /* IMAGE */
345022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj                             Int       noLargerThan )
346022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj{
3473646a495f974e4aacf329e7539a0d584962ff6f6sewardj   Int            i;
3481162491ad6e90572f6417b2dae767ee5694d1e94sewardj   DebugLineInfo  info;
3491162491ad6e90572f6417b2dae767ee5694d1e94sewardj   Bool           is64;
35059e1f3c79e870a978d24add86db6d8c5450c8b63philippe   XArray*        fndn_ix_xa; /* xarray of UInt fndn_ix */
35159e1f3c79e870a978d24add86db6d8c5450c8b63philippe   UInt           fndn_ix;
3521ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian   XArray*        dirname_xa;   /* xarray of const HChar* dirname */
3531ef70c6f00ab1b50d1936f77037e9923d8ed8c59florian   const HChar*   dirname;
3541162491ad6e90572f6417b2dae767ee5694d1e94sewardj
3555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiCursor       external = theBlock;
3565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiCursor       data = theBlock;
357022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
35859e1f3c79e870a978d24add86db6d8c5450c8b63philippe   /* fndn_ix_xa is an xarray of fndn_ix (indexes in di->fndnpool) which
35959e1f3c79e870a978d24add86db6d8c5450c8b63philippe      are build from file names harvested from the DWARF2
36059e1f3c79e870a978d24add86db6d8c5450c8b63philippe      info.  Entry [0] is the "null" pool index and is never referred to
36159e1f3c79e870a978d24add86db6d8c5450c8b63philippe      by the state machine.
362022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
36359e1f3c79e870a978d24add86db6d8c5450c8b63philippe      Similarly, dirname_xa is an xarray of directory names.  Entry [0]
364022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      is also NULL and denotes "we don't know what the path is", since
365022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      that is different from "the path is the empty string".  Unlike
36659e1f3c79e870a978d24add86db6d8c5450c8b63philippe      the fndn_ix_xa table, the state machine does refer to entry [0],
367022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      which basically means "." ("the current directory of the
368022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      compilation", whatever that means, according to the DWARF3
369022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      spec.)
37059e1f3c79e870a978d24add86db6d8c5450c8b63philippe   */
371022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
372022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   /* Fails due to gcc padding ...
373022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   vg_assert(sizeof(DWARF2_External_LineInfo)
374022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj             == sizeof(DWARF2_Internal_LineInfo));
375022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   */
376022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
37759e1f3c79e870a978d24add86db6d8c5450c8b63philippe   dirname_xa = VG_(newXA) (ML_(dinfo_zalloc), "di.rd2l.1", ML_(dinfo_free),
37859e1f3c79e870a978d24add86db6d8c5450c8b63philippe                            sizeof(HChar*) );
37959e1f3c79e870a978d24add86db6d8c5450c8b63philippe   fndn_ix_xa = VG_(newXA) (ML_(dinfo_zalloc), "di.rd2l.2", ML_(dinfo_free),
38059e1f3c79e870a978d24add86db6d8c5450c8b63philippe                            sizeof(UInt) );
381022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
382022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   /* DWARF2 starts numbering filename entries at 1, so we need to
38359e1f3c79e870a978d24add86db6d8c5450c8b63philippe      add a dummy zeroth entry to the table. */
38459e1f3c79e870a978d24add86db6d8c5450c8b63philippe   fndn_ix = 0; // 0 is the "null" index in a fixed pool.
38559e1f3c79e870a978d24add86db6d8c5450c8b63philippe   VG_(addToXA) (fndn_ix_xa, &fndn_ix);
386022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
3875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (ML_(cur_is_valid)(ui->compdir))
38859e1f3c79e870a978d24add86db6d8c5450c8b63philippe      dirname = ML_(addStrFromCursor)(di, ui->compdir);
389022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   else
39059e1f3c79e870a978d24add86db6d8c5450c8b63philippe      dirname = ML_(addStr)(di, ".", -1);
39159e1f3c79e870a978d24add86db6d8c5450c8b63philippe   VG_(addToXA) (dirname_xa, &dirname);
392022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
3935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   info.li_length = step_initial_length_field( &external, &is64 );
394b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (di->ddump_line)
3953646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)("  Length:                      %llu\n",
3963646a495f974e4aacf329e7539a0d584962ff6f6sewardj                  info.li_length);
3973646a495f974e4aacf329e7539a0d584962ff6f6sewardj
398022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   /* Check the length of the block.  */
3991162491ad6e90572f6417b2dae767ee5694d1e94sewardj   if (info.li_length > noLargerThan) {
400b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ML_(symerr)(di, True,
401b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  "DWARF line info appears to be corrupt "
402022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj                  "- the section is too small");
403022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      goto out;
404022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   }
405cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
406022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   /* Check its version number.  */
4075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   info.li_version = ML_(cur_step_UShort)(&external);
408b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (di->ddump_line)
4093646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)("  DWARF Version:               %d\n",
4103646a495f974e4aacf329e7539a0d584962ff6f6sewardj                  (Int)info.li_version);
4113646a495f974e4aacf329e7539a0d584962ff6f6sewardj
412fba428cd266b8a39db641c5fd9523daa8939bed0tom   if (info.li_version != 2 && info.li_version != 3 && info.li_version != 4) {
413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ML_(symerr)(di, True,
414fba428cd266b8a39db641c5fd9523daa8939bed0tom                  "Only DWARF version 2, 3 and 4 line info "
415022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj                  "is currently supported.");
416022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      goto out;
417022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   }
418cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
4195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   info.li_header_length = is64 ? ML_(cur_step_ULong)(&external)
4205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                : (ULong)(ML_(cur_step_UInt)(&external));
421b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (di->ddump_line)
4223646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)("  Prologue Length:             %llu\n",
4233646a495f974e4aacf329e7539a0d584962ff6f6sewardj                  info.li_header_length);
4241162491ad6e90572f6417b2dae767ee5694d1e94sewardj
4255d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   info.li_min_insn_length = ML_(cur_step_UChar)(&external);
426b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (di->ddump_line)
4273646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)("  Minimum Instruction Length:  %d\n",
4283646a495f974e4aacf329e7539a0d584962ff6f6sewardj                  (Int)info.li_min_insn_length);
429cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
430fba428cd266b8a39db641c5fd9523daa8939bed0tom   /* We only support machines with one opcode per instruction
431fba428cd266b8a39db641c5fd9523daa8939bed0tom      for now. If we ever want to support VLIW machines there is
432fba428cd266b8a39db641c5fd9523daa8939bed0tom      code to handle multiple opcodes per instruction in the
433fba428cd266b8a39db641c5fd9523daa8939bed0tom      patch attached to BZ#233595.
434fba428cd266b8a39db641c5fd9523daa8939bed0tom   */
435fba428cd266b8a39db641c5fd9523daa8939bed0tom   if (info.li_version >= 4) {
4365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      info.li_max_ops_per_insn = ML_(cur_step_UChar)(&external);
437fba428cd266b8a39db641c5fd9523daa8939bed0tom      if (info.li_max_ops_per_insn != 1) {
438fba428cd266b8a39db641c5fd9523daa8939bed0tom         ML_(symerr)(di, True,
439fba428cd266b8a39db641c5fd9523daa8939bed0tom                     "Invalid Maximum Ops Per Insn in line info.");
440fba428cd266b8a39db641c5fd9523daa8939bed0tom         goto out;
441fba428cd266b8a39db641c5fd9523daa8939bed0tom      }
442fba428cd266b8a39db641c5fd9523daa8939bed0tom      if (di->ddump_line)
443fba428cd266b8a39db641c5fd9523daa8939bed0tom         VG_(printf)("  Maximum Ops Per Insn:        %d\n",
444fba428cd266b8a39db641c5fd9523daa8939bed0tom                  (Int)info.li_max_ops_per_insn);
445fba428cd266b8a39db641c5fd9523daa8939bed0tom   } else {
446fba428cd266b8a39db641c5fd9523daa8939bed0tom      info.li_max_ops_per_insn = 1;
447fba428cd266b8a39db641c5fd9523daa8939bed0tom   }
448fba428cd266b8a39db641c5fd9523daa8939bed0tom
4495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   info.li_default_is_stmt = ML_(cur_step_UChar)(&external);
450b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (di->ddump_line)
4513646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)("  Initial value of 'is_stmt':  %d\n",
4523646a495f974e4aacf329e7539a0d584962ff6f6sewardj                  (Int)info.li_default_is_stmt);
4533646a495f974e4aacf329e7539a0d584962ff6f6sewardj
454022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   /* Josef Weidendorfer (20021021) writes:
455cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
456022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      It seems to me that the Intel Fortran compiler generates bad
457022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      DWARF2 line info code: It sets "is_stmt" of the state machine in
458ad4e979f408239dabbaae955d8ffcb84a51a5c85florian      the line info reader to be always false. Thus, there is never
459ad4e979f408239dabbaae955d8ffcb84a51a5c85florian      a statement boundary generated and therefore never an instruction
460ad4e979f408239dabbaae955d8ffcb84a51a5c85florian      range/line number mapping generated for valgrind.
461cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
462022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      Please have a look at the DWARF2 specification, Ch. 6.2
463022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      (x86.ddj.com/ftp/manuals/tools/dwarf.pdf).  Perhaps I understand
464022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      this wrong, but I don't think so.
465cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
466022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      I just had a look at the GDB DWARF2 reader...  They completely
467022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      ignore "is_stmt" when recording line info ;-) That's the reason
468ad4e979f408239dabbaae955d8ffcb84a51a5c85florian      "objdump -S" works on files from the intel fortran compiler.
4693646a495f974e4aacf329e7539a0d584962ff6f6sewardj
4703646a495f974e4aacf329e7539a0d584962ff6f6sewardj      Therefore: */
4713646a495f974e4aacf329e7539a0d584962ff6f6sewardj   info.li_default_is_stmt = True;
472cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
473022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   /* JRS: changed (UInt*) to (UChar*) */
4745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   info.li_line_base = ML_(cur_step_UChar)(&external);
4755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   info.li_line_base = (Int)(Char)info.li_line_base;
476b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (di->ddump_line)
4773646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)("  Line Base:                   %d\n",
4783646a495f974e4aacf329e7539a0d584962ff6f6sewardj                  info.li_line_base);
479cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
4805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   info.li_line_range = ML_(cur_step_UChar)(&external);
481b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (di->ddump_line)
4823646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)("  Line Range:                  %d\n",
4833646a495f974e4aacf329e7539a0d584962ff6f6sewardj                  (Int)info.li_line_range);
484cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
4855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   info.li_opcode_base = ML_(cur_step_UChar)(&external);
486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (di->ddump_line)
4873646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)("  Opcode Base:                 %d\n\n",
4883646a495f974e4aacf329e7539a0d584962ff6f6sewardj                  info.li_opcode_base);
489cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
4901162491ad6e90572f6417b2dae767ee5694d1e94sewardj   if (0) VG_(printf)("dwarf2: line base: %d, range %d, opc base: %d\n",
4911162491ad6e90572f6417b2dae767ee5694d1e94sewardj                      (Int)info.li_line_base,
4921162491ad6e90572f6417b2dae767ee5694d1e94sewardj                      (Int)info.li_line_range,
4931162491ad6e90572f6417b2dae767ee5694d1e94sewardj                      (Int)info.li_opcode_base);
494cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
4955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiCursor end_of_sequence
4965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj     = ML_(cur_plus)(data, info.li_length + (is64 ? 12 : 4));
497cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
498022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   reset_state_machine (info.li_default_is_stmt);
499cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
500022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   /* Read the contents of the Opcodes table.  */
5015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiCursor standard_opcodes = external;
502b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (di->ddump_line) {
5033646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)(" Opcodes:\n");
5043646a495f974e4aacf329e7539a0d584962ff6f6sewardj      for (i = 1; i < (Int)info.li_opcode_base; i++) {
5053646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  Opcode %d has %d args\n",
5065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                     i, (Int)ML_(cur_read_UChar)(
5075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                ML_(cur_plus)(standard_opcodes,
5085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                              (i-1) * sizeof(UChar)) ));
5093646a495f974e4aacf329e7539a0d584962ff6f6sewardj      }
5103646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)("\n");
5113646a495f974e4aacf329e7539a0d584962ff6f6sewardj   }
512666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   /* skip over "standard_opcode_lengths" */
5135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   data = ML_(cur_plus)(standard_opcodes, info.li_opcode_base - 1);
514cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
515666ee9df4c2b6d801b199b8168208dbb46573c9dphilippe   /* Read the contents of the Directory table.  */
516b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (di->ddump_line)
5173646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)(" The Directory Table%s\n",
5185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  ML_(cur_read_UChar)(data) == 0 ? " is empty." : ":" );
5193646a495f974e4aacf329e7539a0d584962ff6f6sewardj
5205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   while (ML_(cur_read_UChar)(data) != 0) {
521cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
5225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      HChar* data_str = ML_(cur_read_strdup)(data, "di.rd2l.1");
523b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (di->ddump_line)
5245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         VG_(printf)("  %s\n", data_str);
5253646a495f974e4aacf329e7539a0d584962ff6f6sewardj
526022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      /* If data[0] is '/', then 'data' is an absolute path and we
527c505820a8b10066dcbdcc7ab36b8ae55bd671575florian         don't mess with it.  Otherwise, construct the
5285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         path 'ui->compdir' ++ "/" ++ 'data'. */
529cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
5305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      if (data_str[0] != '/'
531022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj          /* not an absolute path */
5325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj          && ML_(cur_is_valid)(ui->compdir)
5333c5402125cd8f514bf8c6b9774b8fa917896d6b0sewardj          /* actually got something sensible for compdir */
534c505820a8b10066dcbdcc7ab36b8ae55bd671575florian          && ML_(cur_strlen)(ui->compdir))
535022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      {
5365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         HChar* compdir_str = ML_(cur_read_strdup)(ui->compdir, "di.rd2l.1b");
537c505820a8b10066dcbdcc7ab36b8ae55bd671575florian         SizeT  len = VG_(strlen)(compdir_str) + 1 + VG_(strlen)(data_str);
538c505820a8b10066dcbdcc7ab36b8ae55bd671575florian         HChar *buf = ML_(dinfo_zalloc)("di.rd2l.1c", len + 1);
539c505820a8b10066dcbdcc7ab36b8ae55bd671575florian
540c505820a8b10066dcbdcc7ab36b8ae55bd671575florian         VG_(strcpy)(buf, compdir_str);
541022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         VG_(strcat)(buf, "/");
5425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         VG_(strcat)(buf, data_str);
543c505820a8b10066dcbdcc7ab36b8ae55bd671575florian
544c505820a8b10066dcbdcc7ab36b8ae55bd671575florian         dirname = ML_(addStr)(di, buf, len);
54559e1f3c79e870a978d24add86db6d8c5450c8b63philippe         VG_(addToXA) (dirname_xa, &dirname);
546022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         if (0) VG_(printf)("rel path  %s\n", buf);
5475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ML_(dinfo_free)(compdir_str);
548c505820a8b10066dcbdcc7ab36b8ae55bd671575florian         ML_(dinfo_free)(buf);
549022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      } else {
550022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         /* just use 'data'. */
55159e1f3c79e870a978d24add86db6d8c5450c8b63philippe         dirname = ML_(addStr)(di,data_str,-1);
55259e1f3c79e870a978d24add86db6d8c5450c8b63philippe         VG_(addToXA) (dirname_xa, &dirname);
5535d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (0) VG_(printf)("abs path  %s\n", data_str);
554022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      }
555cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf
5565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      data = ML_(cur_plus)(data, VG_(strlen)(data_str) + 1);
5575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      ML_(dinfo_free)(data_str);
558022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   }
5593646a495f974e4aacf329e7539a0d584962ff6f6sewardj
560b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (di->ddump_line)
5613646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)("\n");
5623646a495f974e4aacf329e7539a0d584962ff6f6sewardj
5635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (ML_(cur_read_UChar)(data) != 0) {
564b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ML_(symerr)(di, True,
565b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  "can't find NUL at end of DWARF2 directory table");
566022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      goto out;
567022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   }
5685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   data = ML_(cur_plus)(data, 1);
569022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
570022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   /* Read the contents of the File Name table.  This produces a bunch
57159e1f3c79e870a978d24add86db6d8c5450c8b63philippe      of fndn_ix in fndn_ix_xa. */
572b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (di->ddump_line) {
5733646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)(" The File Name Table:\n");
5743646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)("  Entry	Dir	Time	Size	Name\n");
5753646a495f974e4aacf329e7539a0d584962ff6f6sewardj   }
5763646a495f974e4aacf329e7539a0d584962ff6f6sewardj
5773646a495f974e4aacf329e7539a0d584962ff6f6sewardj   i = 1;
5785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   while (ML_(cur_read_UChar)(data) != 0) {
5795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      HChar* name    = ML_(cur_step_strdup)(&data, "di.rd2l.2");
5805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      Int    diridx  = step_leb128U(&data);
5815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      Int    uu_time = step_leb128U(&data); /* unused */
5825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      Int    uu_size = step_leb128U(&data); /* unused */
58359e1f3c79e870a978d24add86db6d8c5450c8b63philippe
58459e1f3c79e870a978d24add86db6d8c5450c8b63philippe      dirname = safe_dirname_ix( dirname_xa, diridx );
58559e1f3c79e870a978d24add86db6d8c5450c8b63philippe      fndn_ix = ML_(addFnDn) (di, name, dirname);
58659e1f3c79e870a978d24add86db6d8c5450c8b63philippe      VG_(addToXA) (fndn_ix_xa, &fndn_ix);
587022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      if (0) VG_(printf)("file %s diridx %d\n", name, diridx );
588b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (di->ddump_line)
5893646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  %d\t%d\t%d\t%d\t%s\n",
5903646a495f974e4aacf329e7539a0d584962ff6f6sewardj                     i, diridx, uu_time, uu_size, name);
5913646a495f974e4aacf329e7539a0d584962ff6f6sewardj      i++;
5925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      ML_(dinfo_free)(name);
593022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   }
5943646a495f974e4aacf329e7539a0d584962ff6f6sewardj
595b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (di->ddump_line)
5963646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)("\n");
5973646a495f974e4aacf329e7539a0d584962ff6f6sewardj
5985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (ML_(cur_read_UChar)(data) != 0) {
599b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ML_(symerr)(di, True,
600b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                  "can't find NUL at end of DWARF2 file name table");
601022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      goto out;
602022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   }
6035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   data = ML_(cur_plus)(data, 1);
604022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
605b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (di->ddump_line)
6063646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)(" Line Number Statements:\n");
6073646a495f974e4aacf329e7539a0d584962ff6f6sewardj
608022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   /* Now display the statements.  */
609022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
6105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   while (ML_(cur_cmpLT)(data, end_of_sequence)) {
6115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      UChar op_code = ML_(cur_step_UChar)(&data);
612022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
613022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      if (0) VG_(printf)("dwarf2: OPC: %d\n", op_code);
614022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
615022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      if (op_code >= info.li_opcode_base) {
616022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         op_code -= info.li_opcode_base;
6175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         Word adv = (op_code / info.li_line_range)
618022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj                       * info.li_min_insn_length;
6195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         Int advAddr = adv;
620022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         state_machine_regs.address += adv;
6213646a495f974e4aacf329e7539a0d584962ff6f6sewardj
622c6e5d76e9eea8625f385ff844545c688c91938daflorian         if (0) VG_(printf)("smr.a += %#lx\n", (UWord)adv );
623022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         adv = (op_code % info.li_line_range) + info.li_line_base;
624a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart         if (0) VG_(printf)("1002: di->o %#lx, smr.a %#lx\n",
625c6e5d76e9eea8625f385ff844545c688c91938daflorian                            (UWord)di->text_debug_bias,
626c6e5d76e9eea8625f385ff844545c688c91938daflorian                            state_machine_regs.address );
627022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         state_machine_regs.line += adv;
628022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
629b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_line)
6303646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  Special opcode %d: advance Address by %d "
6313646a495f974e4aacf329e7539a0d584962ff6f6sewardj                        "to 0x%lx and Line by %d to %d\n",
6323646a495f974e4aacf329e7539a0d584962ff6f6sewardj                        (Int)op_code, advAddr, state_machine_regs.address,
6333646a495f974e4aacf329e7539a0d584962ff6f6sewardj                        (Int)adv, (Int)state_machine_regs.line );
6343646a495f974e4aacf329e7539a0d584962ff6f6sewardj
635022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         if (state_machine_regs.is_stmt) {
636022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            /* only add a statement if there was a previous boundary */
6371ff57e6a7669ea9ccebd7cc8883e02b477e8597bsewardj            if (state_machine_regs.last_address) {
6387eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardj               ML_(addLineInfo)(
63959e1f3c79e870a978d24add86db6d8c5450c8b63philippe                  di,
64059e1f3c79e870a978d24add86db6d8c5450c8b63philippe                  safe_fndn_ix (fndn_ix_xa,
64159e1f3c79e870a978d24add86db6d8c5450c8b63philippe                                state_machine_regs.last_file),
642402c9eed11b9b60c6e134d05db938e395466cf99tom                  di->text_debug_bias + state_machine_regs.last_address,
643402c9eed11b9b60c6e134d05db938e395466cf99tom                  di->text_debug_bias + state_machine_regs.address,
644022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj                  state_machine_regs.last_line,
645022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj                  0
646022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj               );
6471ff57e6a7669ea9ccebd7cc8883e02b477e8597bsewardj            }
648022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            state_machine_regs.last_address = state_machine_regs.address;
649022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            state_machine_regs.last_file = state_machine_regs.file;
650022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            state_machine_regs.last_line = state_machine_regs.line;
651022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         }
652c613dff23c0f2e971c368fd2b2135df5d3e6b12dsewardj      }
653022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
6543646a495f974e4aacf329e7539a0d584962ff6f6sewardj      else { /* ! (op_code >= info.li_opcode_base) */
6553646a495f974e4aacf329e7539a0d584962ff6f6sewardj
656022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      switch (op_code) {
657022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         case DW_LNS_extended_op:
6585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            process_extended_line_op (
65959e1f3c79e870a978d24add86db6d8c5450c8b63philippe                       di, fndn_ix_xa,
6605d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                       &data, info.li_default_is_stmt);
661022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            break;
662022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
663022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         case DW_LNS_copy:
664a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart            if (0) VG_(printf)("1002: di->o %#lx, smr.a %#lx\n",
665c6e5d76e9eea8625f385ff844545c688c91938daflorian                               (UWord)di->text_debug_bias,
666c6e5d76e9eea8625f385ff844545c688c91938daflorian                               state_machine_regs.address );
667022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            if (state_machine_regs.is_stmt) {
668022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj               /* only add a statement if there was a previous boundary */
6691ff57e6a7669ea9ccebd7cc8883e02b477e8597bsewardj               if (state_machine_regs.last_address) {
6707eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardj                  ML_(addLineInfo)(
67159e1f3c79e870a978d24add86db6d8c5450c8b63philippe                     di,
67259e1f3c79e870a978d24add86db6d8c5450c8b63philippe                     safe_fndn_ix (fndn_ix_xa,
67359e1f3c79e870a978d24add86db6d8c5450c8b63philippe                                   state_machine_regs.last_file),
674402c9eed11b9b60c6e134d05db938e395466cf99tom                     di->text_debug_bias + state_machine_regs.last_address,
675402c9eed11b9b60c6e134d05db938e395466cf99tom                     di->text_debug_bias + state_machine_regs.address,
676022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj                     state_machine_regs.last_line,
677022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj                     0
678022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj                  );
6791ff57e6a7669ea9ccebd7cc8883e02b477e8597bsewardj               }
680022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj               state_machine_regs.last_address = state_machine_regs.address;
681022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj               state_machine_regs.last_file = state_machine_regs.file;
682022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj               state_machine_regs.last_line = state_machine_regs.line;
683022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            }
684022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            state_machine_regs.basic_block = 0; /* JRS added */
685b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (di->ddump_line)
6863646a495f974e4aacf329e7539a0d584962ff6f6sewardj               VG_(printf)("  Copy\n");
687022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            break;
688022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
6895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         case DW_LNS_advance_pc: {
690c6e5d76e9eea8625f385ff844545c688c91938daflorian            UWord adv = info.li_min_insn_length * step_leb128U(&data);
691022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            state_machine_regs.address += adv;
6925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            if (0) VG_(printf)("smr.a += %#lx\n", adv );
693b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (di->ddump_line)
694c6e5d76e9eea8625f385ff844545c688c91938daflorian               VG_(printf)("  Advance PC by %lu to 0x%lx\n",
6955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                           adv, state_machine_regs.address);
696022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            break;
6975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
6985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         case DW_LNS_advance_line: {
6995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            Word adv = step_leb128S(&data);
700022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            state_machine_regs.line += adv;
701b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (di->ddump_line)
7025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               VG_(printf)("  Advance Line by %ld to %d\n",
7035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                           adv, (Int)state_machine_regs.line);
704022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            break;
7055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
7065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         case DW_LNS_set_file: {
7075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            Word adv = step_leb128U(&data);
708022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            state_machine_regs.file = adv;
709b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (di->ddump_line)
7105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               VG_(printf)("  Set File Name to entry %ld in the "
7115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                           "File Name Table\n", adv);
712022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            break;
7135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
7145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         case DW_LNS_set_column: {
7155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            Word adv = step_leb128U(&data);
716022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            state_machine_regs.column = adv;
717b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (di->ddump_line)
7185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               VG_(printf)("  Set column to %ld\n", adv);
719022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            break;
7205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
7215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         case DW_LNS_negate_stmt: {
7225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            Int adv = state_machine_regs.is_stmt;
723022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            adv = ! adv;
724022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            state_machine_regs.is_stmt = adv;
725b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (di->ddump_line)
7263646a495f974e4aacf329e7539a0d584962ff6f6sewardj               VG_(printf)("  DWARF2-line: negate_stmt\n");
727022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            break;
7285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
7295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         case DW_LNS_set_basic_block: {
730022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            state_machine_regs.basic_block = 1;
731b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (di->ddump_line)
7323646a495f974e4aacf329e7539a0d584962ff6f6sewardj               VG_(printf)("  DWARF2-line: set_basic_block\n");
733022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            break;
7345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
7355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         case DW_LNS_const_add_pc: {
7365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            Word adv = (((255 - info.li_opcode_base) / info.li_line_range)
7375d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                          * info.li_min_insn_length);
738022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            state_machine_regs.address += adv;
739c6e5d76e9eea8625f385ff844545c688c91938daflorian            if (0) VG_(printf)("smr.a += %#lx\n", (UWord)adv );
740b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (di->ddump_line)
7415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               VG_(printf)("  Advance PC by constant %ld to 0x%lx\n",
7425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                           adv, (Addr)state_machine_regs.address);
743022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            break;
7445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
7455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         case DW_LNS_fixed_advance_pc: {
746022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            /* XXX: Need something to get 2 bytes */
747c6e5d76e9eea8625f385ff844545c688c91938daflorian            UWord adv = ML_(cur_step_UShort)(&data);
748022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            state_machine_regs.address += adv;
7495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            if (0) VG_(printf)("smr.a += %#lx\n", adv );
750b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (di->ddump_line)
7513646a495f974e4aacf329e7539a0d584962ff6f6sewardj               VG_(printf)("  DWARF2-line: fixed_advance_pc\n");
752022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            break;
7535d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
754022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         case DW_LNS_set_prologue_end:
755b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (di->ddump_line)
7563646a495f974e4aacf329e7539a0d584962ff6f6sewardj               VG_(printf)("  DWARF2-line: set_prologue_end\n");
757022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            break;
758022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
759022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         case DW_LNS_set_epilogue_begin:
760b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (di->ddump_line)
7613646a495f974e4aacf329e7539a0d584962ff6f6sewardj               VG_(printf)("  DWARF2-line: set_epilogue_begin\n");
762022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            break;
763022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
764022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         case DW_LNS_set_isa:
7655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            (void)step_leb128U(&data);
766b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (di->ddump_line)
7673646a495f974e4aacf329e7539a0d584962ff6f6sewardj               VG_(printf)("  DWARF2-line: set_isa\n");
768022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            break;
769022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
770022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         default: {
771022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            Int j;
7725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            for (j = (Int)ML_(cur_read_UChar)(
7735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                             ML_(cur_plus)(standard_opcodes,
7745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                           (op_code-1) * sizeof(UChar)));
7755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                 j > 0 ; --j) {
7765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               step_leb128U(&data);
777022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            }
778b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (di->ddump_line)
7793646a495f974e4aacf329e7539a0d584962ff6f6sewardj               VG_(printf)("  Unknown opcode %d\n", (Int)op_code);
7803646a495f974e4aacf329e7539a0d584962ff6f6sewardj            break;
781022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         }
782022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      } /* switch (op_code) */
783022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
7843646a495f974e4aacf329e7539a0d584962ff6f6sewardj      } /* if (op_code >= info.li_opcode_base) */
7853646a495f974e4aacf329e7539a0d584962ff6f6sewardj
786022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   } /* while (data < end_of_sequence) */
787022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
788b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (di->ddump_line)
7893646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)("\n");
7903646a495f974e4aacf329e7539a0d584962ff6f6sewardj
791022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj  out:
79259e1f3c79e870a978d24add86db6d8c5450c8b63philippe   VG_(deleteXA)(dirname_xa);
79359e1f3c79e870a978d24add86db6d8c5450c8b63philippe   VG_(deleteXA)(fndn_ix_xa);
794022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj}
795022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
796022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj////////////////////////////////////////////////////////////////////
797022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj////////////////////////////////////////////////////////////////////
798022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
799022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj/* Return abbrev for given code
8005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj * Returned cursor points to the tag
801022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj * */
8025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic DiCursor lookup_abbrev( DiCursor p, ULong acode )
803022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj{
8045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   while (1) {
8055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      ULong code = step_leb128U(&p);
8065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      if (code == acode)
807022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         return p;
8085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      (void)step_leb128U(&p);  /* skip tag */
8095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      p = ML_(cur_plus)(p,1);  /* skip has_children flag */
8105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      ULong name;
811022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      do {
8125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         name = step_leb128U(&p); /* name */
8135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         (void)step_leb128U(&p);  /* form */
814cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf      }
8155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      while (name != 0); /* until name == form == 0 */
816022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   }
817022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj}
818022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
819022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj/* Read general information for a particular compile unit block in
8204c3b2379fb2cb97f762617df7770b042b1f8a59cmjw * the .debug_info section. In particular read the name, compdir and
8214c3b2379fb2cb97f762617df7770b042b1f8a59cmjw * stmt_list needed to parse the line number information.
822022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj *
823022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj * Input: - unitblock is the start of a compilation
824022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj *          unit block in .debuginfo section
825022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj *        - debugabbrev is start of .debug_abbrev section
826022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj *        - debugstr is start of .debug_str section
8274c3b2379fb2cb97f762617df7770b042b1f8a59cmjw *        - debugstr_alt_img is start of .debug_str section in alt debug file
828022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj *
829022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj * Output: Fill members of ui pertaining to the compilation unit:
830022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj *         - ui->name is the name of the compilation unit
831022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj *         - ui->compdir is the compilation unit directory
832022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj *         - ui->stmt_list is the offset in .debug_line section
833022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj *                for the dbginfos of this compilation unit
834022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj *
835022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj * Note : the output strings are not allocated and point
836022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj * directly to the memory-mapped section.
837022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj */
838022bf2fa104dbad3451c9b95265e2979a4d5faafsewardjstatic
839022bf2fa104dbad3451c9b95265e2979a4d5faafsewardjvoid read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui,
8405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                  DiCursor  unitblock_img,
8415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                  DiCursor  debugabbrev_img,
8425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                  DiCursor  debugstr_img,
8435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                  DiCursor  debugstr_alt_img )
844022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj{
8451162491ad6e90572f6417b2dae767ee5694d1e94sewardj   UInt   acode, abcode;
8461162491ad6e90572f6417b2dae767ee5694d1e94sewardj   ULong  atoffs, blklen;
84758d9ce4730d95103c9388be264a170ab852432a9mjw   UShort ver;
848022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
8495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UChar    addr_size;
8505d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiCursor p = unitblock_img;
8515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiCursor end_img;
8525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiCursor abbrev_img;
853022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
854022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   VG_(memset)( ui, 0, sizeof( UnitInfo ) );
8551162491ad6e90572f6417b2dae767ee5694d1e94sewardj   ui->stmt_list = -1LL;
856022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
8571162491ad6e90572f6417b2dae767ee5694d1e94sewardj   /* Read the compilation unit header in .debug_info section - See p 70 */
858022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
8591162491ad6e90572f6417b2dae767ee5694d1e94sewardj   /* This block length */
8605d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   blklen = step_initial_length_field( &p, &ui->dw64 );
8611162491ad6e90572f6417b2dae767ee5694d1e94sewardj
862fba428cd266b8a39db641c5fd9523daa8939bed0tom   /* version should be 2, 3 or 4 */
8635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   ver = ML_(cur_step_UShort)(&p);
8641162491ad6e90572f6417b2dae767ee5694d1e94sewardj
8651162491ad6e90572f6417b2dae767ee5694d1e94sewardj   /* get offset in abbrev */
8665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   atoffs = ui->dw64 ? ML_(cur_step_ULong)(&p)
8675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                     : (ULong)(ML_(cur_step_UInt)(&p));
8681162491ad6e90572f6417b2dae767ee5694d1e94sewardj
8691162491ad6e90572f6417b2dae767ee5694d1e94sewardj   /* Address size */
8705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   addr_size = ML_(cur_step_UChar)(&p);
8711162491ad6e90572f6417b2dae767ee5694d1e94sewardj
8725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   /* End of this block */
8735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   end_img = ML_(cur_plus)(unitblock_img, blklen + (ui->dw64 ? 12 : 4));
8745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
8755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   /* Abbreviation data for this block */
8765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   abbrev_img = ML_(cur_plus)(debugabbrev_img, atoffs);
877022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
8784c3b2379fb2cb97f762617df7770b042b1f8a59cmjw   /* Read the compilation unit entry - this is always the first DIE.
8794c3b2379fb2cb97f762617df7770b042b1f8a59cmjw    * See DWARF4 para 7.5. */
8805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (ML_(cur_cmpLT)(p, end_img)) {
881022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      UInt tag;
882022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
8835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      acode = step_leb128U( &p ); /* abbreviation code */
884022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
885022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      /* Read abbreviation header */
8865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      abcode = step_leb128U( &abbrev_img ); /* abbreviation code */
887022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      if ( acode != abcode ) {
8884c3b2379fb2cb97f762617df7770b042b1f8a59cmjw         /* This isn't illegal, but somewhat unlikely. Normally the
8894c3b2379fb2cb97f762617df7770b042b1f8a59cmjw          * first abbrev describes the first DIE, the compile_unit.
8904c3b2379fb2cb97f762617df7770b042b1f8a59cmjw          * But maybe this abbrevation data is shared with another
8914c3b2379fb2cb97f762617df7770b042b1f8a59cmjw          * or it is a NULL entry used for padding. See para 7.5.3. */
8925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         abbrev_img = lookup_abbrev( ML_(cur_plus)(debugabbrev_img, atoffs),
8935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                     acode );
894022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      }
895022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
8965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      tag = step_leb128U( &abbrev_img );
897022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
8984c3b2379fb2cb97f762617df7770b042b1f8a59cmjw      if ( tag != 0x0011 /*TAG_compile_unit*/ )
8994c3b2379fb2cb97f762617df7770b042b1f8a59cmjw         return; /* Not a compile unit (might be partial) or broken DWARF. */
9004c3b2379fb2cb97f762617df7770b042b1f8a59cmjw
9015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      /* DW_CHILDREN_yes or DW_CHILDREN_no */
9025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      abbrev_img = ML_(cur_plus)(abbrev_img, 1);
903022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
904022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      /* And loop on entries */
905022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      for ( ; ; ) {
906022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         /* Read entry definition */
9075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    cval = -1LL;  /* Constant value read */
9085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor sval = DiCursor_INVALID; /* String value read */
9095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UInt     name = step_leb128U( &abbrev_img );
9105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UInt     form = step_leb128U( &abbrev_img );
9115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (name == 0)
912022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            break;
913022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
914022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         /* Read data */
915022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         /* Attributes encoding explained p 71 */
916022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         if ( form == 0x16 /* FORM_indirect */ )
9175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            form = step_leb128U( &p );
918022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         /* Decode form. For most kinds, Just skip the amount of data since
919022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            we don't use it for now */
9201162491ad6e90572f6417b2dae767ee5694d1e94sewardj         /* JRS 9 Feb 06: This now handles 64-bit DWARF too.  In
9211162491ad6e90572f6417b2dae767ee5694d1e94sewardj            64-bit DWARF, lineptr (and loclistptr,macptr,rangelistptr
9221162491ad6e90572f6417b2dae767ee5694d1e94sewardj            classes) use FORM_data8, not FORM_data4.  Also,
9231162491ad6e90572f6417b2dae767ee5694d1e94sewardj            FORM_ref_addr and FORM_strp are 64-bit values, not 32-bit
9241162491ad6e90572f6417b2dae767ee5694d1e94sewardj            values. */
925fba428cd266b8a39db641c5fd9523daa8939bed0tom         /* TJH 27 Apr 10: in DWARF 4 lineptr (and loclistptr,macptr,
926fba428cd266b8a39db641c5fd9523daa8939bed0tom            rangelistptr classes) use FORM_sec_offset which is 64 bits
927fba428cd266b8a39db641c5fd9523daa8939bed0tom            in 64 bit DWARF and 32 bits in 32 bit DWARF. */
92806938afc5606be015c4793da47d70ef987ef631dsewardj         /* JRS 20 Apr 11: LLVM-2.9 encodes DW_AT_stmt_list using
92906938afc5606be015c4793da47d70ef987ef631dsewardj            FORM_addr rather than the FORM_data4 that GCC uses.  Hence
93006938afc5606be015c4793da47d70ef987ef631dsewardj            handle FORM_addr too. */
931022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         switch( form ) {
932022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            /* Those cases extract the data properly */
9335d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x05: /* FORM_data2 */
9345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               cval = ML_(cur_step_UShort)(&p);
9355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
9365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x06: /* FORM_data4 */
9375d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               cval = ML_(cur_step_UInt)(&p);
9385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
9391a0e39feedac83377a8a10ee5052c4abccb69f22sewardj            case 0x0e: /* FORM_strp */      /* pointer in .debug_str */
9405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               /* 2006-01-01: only generate a value if a debug_str
9415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  section was found) */
9425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               if (ML_(cur_is_valid)(debugstr_img) && !ui->dw64)
9435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  sval = ML_(cur_plus)(debugstr_img, ML_(cur_read_UInt)(p));
9445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               if (ML_(cur_is_valid)(debugstr_img) && ui->dw64)
9455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  sval = ML_(cur_plus)(debugstr_img, ML_(cur_read_ULong)(p));
9465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               p = ML_(cur_plus)(p, ui->dw64 ? 8 : 4);
9475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
9485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x08: /* FORM_string */
9495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               sval = p;
9505d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               p = ML_(cur_plus)(p, ML_(cur_strlen)(p) + 1);
9515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
9525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x0b: /* FORM_data1 */
9535d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               cval = ML_(cur_step_UChar)(&p);
9545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
9555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x17: /* FORM_sec_offset */
9565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               if (ui->dw64) {
9575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                 cval = ML_(cur_step_ULong)(&p);
9585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               } else {
9595d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                 cval = ML_(cur_step_UInt)(&p);
9605d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               };
9615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
9625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x07: /* FORM_data8 */
9635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               if (ui->dw64) cval = ML_(cur_read_ULong)(p);
9645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               p = ML_(cur_plus)(p, 8);
9655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               /* perhaps should assign unconditionally to cval? */
9665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
967022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            /* TODO : Following ones just skip data - implement if you need */
9685d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x01: /* FORM_addr */
9695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               p = ML_(cur_plus)(p, addr_size);
9705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
9715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x03: /* FORM_block2 */
9725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               p = ML_(cur_plus)(p, ML_(cur_read_UShort)(p) + 2);
9735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
9745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x04: /* FORM_block4 */
9755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               p = ML_(cur_plus)(p, ML_(cur_read_UInt)(p) + 4);
9765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
9775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x09:   /* FORM_block */     /* fallthrough */
9785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x18: { /* FORM_exprloc */
9795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               ULong block_len = step_leb128U(&p);
9805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               p = ML_(cur_plus)(p, block_len);
9815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
9825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            }
9835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x0a: /* FORM_block1 */
9845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               p = ML_(cur_plus)(p, ML_(cur_read_UChar)(p) + 1);
9855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
9865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x0c: /* FORM_flag */
9875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               p = ML_(cur_plus)(p, 1);
9885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
9895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x0d: /* FORM_sdata */
9905d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               (void)step_leb128S(&p);
9915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
9925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x0f: /* FORM_udata */
9935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               (void)step_leb128U(&p);
9945d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
9955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x10: /* FORM_ref_addr */
9965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               p = ML_(cur_plus)(p, (ver == 2) ? addr_size
9975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                               : (ui->dw64 ? 8 : 4));
9985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
9995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x11: /* FORM_ref1 */
10005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               p = ML_(cur_plus)(p, 1);
10015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
10025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x12: /* FORM_ref2 */
10035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               p = ML_(cur_plus)(p, 2);
10045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
10055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x13: /* FORM_ref4 */
10065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               p = ML_(cur_plus)(p, 4);
10075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
10085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x14: /* FORM_ref8 */
10095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               p = ML_(cur_plus)(p, 8);
10105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
10115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x15: /* FORM_ref_udata */
10125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               (void)step_leb128U(&p);
10135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
10145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x19: /* FORM_flag_present */
10155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
10165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x20: /* FORM_ref_sig8 */
10175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               p = ML_(cur_plus)(p, 8);
10185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
10195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            case 0x1f20: /* FORM_GNU_ref_alt */
10205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               p = ML_(cur_plus)(p, ui->dw64 ? 8 : 4);
10215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
1022f7c9714ea0cde18daaecb896278e85e780d3bd75sewardj            case 0x1f21: /* FORM_GNU_strp_alt */
10235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               if (ML_(cur_is_valid)(debugstr_alt_img) && !ui->dw64)
10245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  sval = ML_(cur_plus)(debugstr_alt_img,
10255d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       ML_(cur_read_UInt)(p));
10265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               if (ML_(cur_is_valid)(debugstr_alt_img) && ui->dw64)
10275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  sval = ML_(cur_plus)(debugstr_alt_img,
10285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       ML_(cur_read_ULong)(p));
10295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               p = ML_(cur_plus)(p, ui->dw64 ? 8 : 4);
10305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               break;
1031fba428cd266b8a39db641c5fd9523daa8939bed0tom
1032022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            default:
10335d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               VG_(printf)( "### unhandled dwarf2 abbrev form code 0x%x\n",
10345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                            form );
1035022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj               break;
1036022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         }
1037022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
1038022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         /* Now store the members we need in the UnitInfo structure */
1039022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         if ( tag == 0x0011 /*TAG_compile_unit*/ ) {
1040022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj                 if ( name == 0x03 ) ui->name = sval;      /* DW_AT_name */
1041022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            else if ( name == 0x1b ) ui->compdir = sval;   /* DW_AT_compdir */
1042022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj            else if ( name == 0x10 ) ui->stmt_list = cval; /* DW_AT_stmt_list */
1043022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         }
1044022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      }
10454c3b2379fb2cb97f762617df7770b042b1f8a59cmjw   } /* Just read the first DIE, if that wasn't the compile_unit then
10464c3b2379fb2cb97f762617df7770b042b1f8a59cmjw      * this might have been a partial unit or broken DWARF info.
10474c3b2379fb2cb97f762617df7770b042b1f8a59cmjw      * That's enough info for us, and we are not gdb ! */
1048022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj}
1049c613dff23c0f2e971c368fd2b2135df5d3e6b12dsewardj
1050c613dff23c0f2e971c368fd2b2135df5d3e6b12dsewardj
1051022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj////////////////////////////////////////////////////////////////////
1052022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj////////////////////////////////////////////////////////////////////
1053022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
1054b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj/* Collect the debug info from DWARF3 debugging sections
1055022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj * of a given module.
1056022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj *
1057022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj * Inputs: given .debug_xxx sections
1058b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj * Output: update di to contain all the DWARF3 debug infos
1059022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj */
1060b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjvoid ML_(read_debuginfo_dwarf3)
1061b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        ( struct _DebugInfo* di,
10625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj          DiSlice escn_debug_info,      /* .debug_info */
10635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj          DiSlice escn_debug_types,     /* .debug_types */
10645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj          DiSlice escn_debug_abbv,      /* .debug_abbrev */
10655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj          DiSlice escn_debug_line,      /* .debug_line */
10665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj          DiSlice escn_debug_str,       /* .debug_str */
10675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj          DiSlice escn_debug_str_alt )  /* .debug_str */
1068022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj{
1069022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   UnitInfo ui;
10701162491ad6e90572f6417b2dae767ee5694d1e94sewardj   UShort   ver;
10711162491ad6e90572f6417b2dae767ee5694d1e94sewardj   ULong    blklen;
10721162491ad6e90572f6417b2dae767ee5694d1e94sewardj   Bool     blklen_is_64;
1073022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
107450d01ab68a75fffb927d03410a6dc232baeb28cdtom   /* Make sure we at least have a header for the first block */
10755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (escn_debug_info.szB < 4) {
1076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      ML_(symerr)( di, True,
1077b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   "Last block truncated in .debug_info; ignoring" );
107850d01ab68a75fffb927d03410a6dc232baeb28cdtom      return;
107950d01ab68a75fffb927d03410a6dc232baeb28cdtom   }
108050d01ab68a75fffb927d03410a6dc232baeb28cdtom
10815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiCursor block_img = DiCursor_INVALID;
10825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiCursor end1_img  = ML_(cur_plus)( ML_(cur_from_sli)(escn_debug_info),
10835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                       escn_debug_info.szB );
10845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   Int blklen_len = 0;
10855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1086022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   /* Iterate on all the blocks we find in .debug_info */
10875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   for ( block_img = ML_(cur_from_sli)(escn_debug_info);
10885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ML_(cur_cmpLT)(block_img, ML_(cur_plus)(end1_img, -(DiOffT)4));
10895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         block_img = ML_(cur_plus)(block_img, blklen + blklen_len) ) {
1090022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
1091022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      /* Read the compilation unit header in .debug_info section - See
1092022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         p 70 */
10931162491ad6e90572f6417b2dae767ee5694d1e94sewardj      /* This block length */
1094f767d967b9ef331dcd7d0cd4584f6570cd829333sewardj      blklen     = read_initial_length_field( block_img, &blklen_is_64 );
10951162491ad6e90572f6417b2dae767ee5694d1e94sewardj      blklen_len = blklen_is_64 ? 12 : 4;
10965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
10975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      if (ML_(cur_cmpGT)( ML_(cur_plus)(block_img, blklen + blklen_len),
10985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                          end1_img )) {
1099b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ML_(symerr)( di, True,
1100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                      "Last block truncated in .debug_info; ignoring" );
1101022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         return;
1102c613dff23c0f2e971c368fd2b2135df5d3e6b12dsewardj      }
11031162491ad6e90572f6417b2dae767ee5694d1e94sewardj
11041162491ad6e90572f6417b2dae767ee5694d1e94sewardj      /* version should be 2 */
11055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      ver = ML_(cur_read_UShort)( ML_(cur_plus)(block_img, blklen_len) );
1106fba428cd266b8a39db641c5fd9523daa8939bed0tom      if ( ver != 2 && ver != 3 && ver != 4 ) {
1107b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         ML_(symerr)( di, True,
1108fba428cd266b8a39db641c5fd9523daa8939bed0tom                      "Ignoring non-Dwarf2/3/4 block in .debug_info" );
1109022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         continue;
1110cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf      }
1111022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
1112022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      /* Fill ui with offset in .debug_line and compdir */
11131162491ad6e90572f6417b2dae767ee5694d1e94sewardj      if (0)
11145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         VG_(printf)(
11155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            "Reading UnitInfo at 0x%llx.....\n",
11165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            (ULong)ML_(cur_minus)( block_img,
11175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                   ML_(cur_from_sli)(escn_debug_info)) );
1118b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      read_unitinfo_dwarf2( &ui, block_img,
11195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                 ML_(cur_from_sli)(escn_debug_abbv),
11205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                 ML_(cur_from_sli)(escn_debug_str),
11215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                 ML_(cur_from_sli)(escn_debug_str_alt) );
11225d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      if (0) {
11235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         HChar* str_name    = ML_(cur_read_strdup)(ui.name,    "di.rdd3.1");
11245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         HChar* str_compdir = ML_(cur_read_strdup)(ui.compdir, "di.rdd3.2");
11251162491ad6e90572f6417b2dae767ee5694d1e94sewardj         VG_(printf)( "   => LINES=0x%llx    NAME=%s     DIR=%s\n",
11265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                      ui.stmt_list, str_name, str_compdir );
11275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ML_(dinfo_free)(str_name);
11285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ML_(dinfo_free)(str_compdir);
11295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      }
11305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1131022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      /* Ignore blocks with no .debug_line associated block */
11321162491ad6e90572f6417b2dae767ee5694d1e94sewardj      if ( ui.stmt_list == -1LL )
1133022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj         continue;
1134022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
11355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      if (0) {
11365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         HChar* str_name = ML_(cur_read_strdup)(ui.name, "di.rdd3.3");
1137c6e5d76e9eea8625f385ff844545c688c91938daflorian         VG_(printf)("debug_line_sz %llu, ui.stmt_list %llu  %s\n",
11385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                     escn_debug_line.szB, ui.stmt_list, str_name );
11395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ML_(dinfo_free)(str_name);
11405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      }
11415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
1142022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj      /* Read the .debug_line block for this compile unit */
11435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      read_dwarf2_lineblock(
11445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         di, &ui,
11455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ML_(cur_plus)(ML_(cur_from_sli)(escn_debug_line), ui.stmt_list),
11465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         escn_debug_line.szB  - ui.stmt_list
11475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      );
1148022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj   }
1149cb1d1c0042661ad70f21f56d1317779ba5dd1dd1jsgf}
11504bbdc9756d8750b77759b31da2dbebffaf957b5enjn
11518b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
1152022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj////////////////////////////////////////////////////////////////////
1153022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj////////////////////////////////////////////////////////////////////
1154022bf2fa104dbad3451c9b95265e2979a4d5faafsewardj
11558b3131a0c22c3d22f5ad344990acd81bad1f718fjseward/*------------------------------------------------------------*/
11568b3131a0c22c3d22f5ad344990acd81bad1f718fjseward/*--- Read DWARF1 format line number info.                 ---*/
11578b3131a0c22c3d22f5ad344990acd81bad1f718fjseward/*------------------------------------------------------------*/
11588b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
11598b3131a0c22c3d22f5ad344990acd81bad1f718fjseward/* DWARF1 appears to be redundant, but nevertheless the Lahey Fortran
11608b3131a0c22c3d22f5ad344990acd81bad1f718fjseward   compiler generates it.
11618b3131a0c22c3d22f5ad344990acd81bad1f718fjseward*/
11628b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
11638b3131a0c22c3d22f5ad344990acd81bad1f718fjseward/* The following three enums (dwarf_tag, dwarf_form, dwarf_attribute)
11648b3131a0c22c3d22f5ad344990acd81bad1f718fjseward   are taken from the file include/elf/dwarf.h in the GNU gdb-6.0
11658b3131a0c22c3d22f5ad344990acd81bad1f718fjseward   sources, which are Copyright 1992, 1993, 1995, 1999 Free Software
11668b3131a0c22c3d22f5ad344990acd81bad1f718fjseward   Foundation, Inc and naturally licensed under the GNU General Public
11678b3131a0c22c3d22f5ad344990acd81bad1f718fjseward   License version 2 or later.
11688b3131a0c22c3d22f5ad344990acd81bad1f718fjseward*/
11698b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
11708b3131a0c22c3d22f5ad344990acd81bad1f718fjseward/* Tag names and codes.  */
11718b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
11728b3131a0c22c3d22f5ad344990acd81bad1f718fjsewardenum dwarf_tag {
11738b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_padding			= 0x0000,
11748b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_array_type		= 0x0001,
11758b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_class_type		= 0x0002,
11768b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_entry_point		= 0x0003,
11778b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_enumeration_type	= 0x0004,
11788b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_formal_parameter	= 0x0005,
11798b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_global_subroutine	= 0x0006,
11808b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_global_variable		= 0x0007,
11818b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    				/* 0x0008 -- reserved */
11828b3131a0c22c3d22f5ad344990acd81bad1f718fjseward				/* 0x0009 -- reserved */
11838b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_label			= 0x000a,
11848b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_lexical_block		= 0x000b,
11858b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_local_variable		= 0x000c,
11868b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_member			= 0x000d,
11878b3131a0c22c3d22f5ad344990acd81bad1f718fjseward				/* 0x000e -- reserved */
11888b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_pointer_type		= 0x000f,
11898b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_reference_type		= 0x0010,
11908b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_compile_unit		= 0x0011,
11918b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_string_type		= 0x0012,
11928b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_structure_type		= 0x0013,
11938b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_subroutine		= 0x0014,
11948b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_subroutine_type		= 0x0015,
11958b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_typedef			= 0x0016,
11968b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_union_type		= 0x0017,
11978b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_unspecified_parameters	= 0x0018,
11988b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_variant			= 0x0019,
11998b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_common_block		= 0x001a,
12008b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_common_inclusion	= 0x001b,
12018b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_inheritance		= 0x001c,
12028b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_inlined_subroutine	= 0x001d,
12038b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_module			= 0x001e,
12048b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_ptr_to_member_type	= 0x001f,
12058b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_set_type		= 0x0020,
12068b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_subrange_type		= 0x0021,
12078b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_with_stmt		= 0x0022,
12088b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
12098b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    /* GNU extensions */
12108b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
12118b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_format_label		= 0x8000,  /* for FORTRAN 77 and Fortran 90 */
12128b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_namelist		= 0x8001,  /* For Fortran 90 */
12138b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_function_template	= 0x8002,  /* for C++ */
12148b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    TAG_class_template		= 0x8003   /* for C++ */
12158b3131a0c22c3d22f5ad344990acd81bad1f718fjseward};
12168b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
12178b3131a0c22c3d22f5ad344990acd81bad1f718fjseward/* Form names and codes.  */
12188b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
12198b3131a0c22c3d22f5ad344990acd81bad1f718fjsewardenum dwarf_form {
12208b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    FORM_ADDR	= 0x1,
12218b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    FORM_REF	= 0x2,
12228b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    FORM_BLOCK2	= 0x3,
12238b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    FORM_BLOCK4	= 0x4,
12248b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    FORM_DATA2	= 0x5,
12258b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    FORM_DATA4	= 0x6,
12268b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    FORM_DATA8	= 0x7,
12278b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    FORM_STRING	= 0x8
12288b3131a0c22c3d22f5ad344990acd81bad1f718fjseward};
12298b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
12308b3131a0c22c3d22f5ad344990acd81bad1f718fjseward/* Attribute names and codes.  */
12318b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
12328b3131a0c22c3d22f5ad344990acd81bad1f718fjsewardenum dwarf_attribute {
12338b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_sibling			= (0x0010|FORM_REF),
12348b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_location			= (0x0020|FORM_BLOCK2),
12358b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_name			= (0x0030|FORM_STRING),
12368b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_fund_type		= (0x0050|FORM_DATA2),
12378b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_mod_fund_type		= (0x0060|FORM_BLOCK2),
12388b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_user_def_type		= (0x0070|FORM_REF),
12398b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_mod_u_d_type		= (0x0080|FORM_BLOCK2),
12408b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_ordering			= (0x0090|FORM_DATA2),
12418b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_subscr_data		= (0x00a0|FORM_BLOCK2),
12428b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_byte_size		= (0x00b0|FORM_DATA4),
12438b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_bit_offset		= (0x00c0|FORM_DATA2),
12448b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_bit_size			= (0x00d0|FORM_DATA4),
12458b3131a0c22c3d22f5ad344990acd81bad1f718fjseward				/* (0x00e0|FORM_xxxx) -- reserved */
12468b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_element_list		= (0x00f0|FORM_BLOCK4),
12478b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_stmt_list		= (0x0100|FORM_DATA4),
12488b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_low_pc			= (0x0110|FORM_ADDR),
12498b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_high_pc			= (0x0120|FORM_ADDR),
12508b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_language			= (0x0130|FORM_DATA4),
12518b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_member			= (0x0140|FORM_REF),
12528b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_discr			= (0x0150|FORM_REF),
12538b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_discr_value		= (0x0160|FORM_BLOCK2),
12548b3131a0c22c3d22f5ad344990acd81bad1f718fjseward				/* (0x0170|FORM_xxxx) -- reserved */
12558b3131a0c22c3d22f5ad344990acd81bad1f718fjseward				/* (0x0180|FORM_xxxx) -- reserved */
12568b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_string_length		= (0x0190|FORM_BLOCK2),
12578b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_common_reference		= (0x01a0|FORM_REF),
12588b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_comp_dir			= (0x01b0|FORM_STRING),
12598b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        AT_const_value_string	= (0x01c0|FORM_STRING),
12608b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        AT_const_value_data2	= (0x01c0|FORM_DATA2),
12618b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        AT_const_value_data4	= (0x01c0|FORM_DATA4),
12628b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        AT_const_value_data8	= (0x01c0|FORM_DATA8),
12638b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        AT_const_value_block2	= (0x01c0|FORM_BLOCK2),
12648b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        AT_const_value_block4	= (0x01c0|FORM_BLOCK4),
12658b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_containing_type		= (0x01d0|FORM_REF),
12668b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        AT_default_value_addr	= (0x01e0|FORM_ADDR),
12678b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        AT_default_value_data2	= (0x01e0|FORM_DATA2),
12688b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        AT_default_value_data4	= (0x01e0|FORM_DATA4),
12698b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        AT_default_value_data8	= (0x01e0|FORM_DATA8),
12708b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        AT_default_value_string	= (0x01e0|FORM_STRING),
12718b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_friends			= (0x01f0|FORM_BLOCK2),
12728b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_inline			= (0x0200|FORM_STRING),
12738b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_is_optional		= (0x0210|FORM_STRING),
12748b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        AT_lower_bound_ref	= (0x0220|FORM_REF),
12758b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        AT_lower_bound_data2	= (0x0220|FORM_DATA2),
12768b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        AT_lower_bound_data4	= (0x0220|FORM_DATA4),
12778b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        AT_lower_bound_data8	= (0x0220|FORM_DATA8),
12788b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_private			= (0x0240|FORM_STRING),
12798b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_producer			= (0x0250|FORM_STRING),
12808b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_program			= (0x0230|FORM_STRING),
12818b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_protected		= (0x0260|FORM_STRING),
12828b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_prototyped		= (0x0270|FORM_STRING),
12838b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_public			= (0x0280|FORM_STRING),
12848b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_pure_virtual		= (0x0290|FORM_STRING),
12858b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_return_addr		= (0x02a0|FORM_BLOCK2),
12868b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_abstract_origin		= (0x02b0|FORM_REF),
12878b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_start_scope		= (0x02c0|FORM_DATA4),
12888b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_stride_size		= (0x02e0|FORM_DATA4),
12898b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        AT_upper_bound_ref	= (0x02f0|FORM_REF),
12908b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        AT_upper_bound_data2	= (0x02f0|FORM_DATA2),
12918b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        AT_upper_bound_data4	= (0x02f0|FORM_DATA4),
12928b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        AT_upper_bound_data8	= (0x02f0|FORM_DATA8),
12938b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_virtual			= (0x0300|FORM_STRING),
12948b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
12958b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    /* GNU extensions.  */
12968b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
12978b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_sf_names			= (0x8000|FORM_DATA4),
12988b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_src_info			= (0x8010|FORM_DATA4),
12998b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_mac_info			= (0x8020|FORM_DATA4),
13008b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_src_coords		= (0x8030|FORM_DATA4),
13018b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_body_begin		= (0x8040|FORM_ADDR),
13028b3131a0c22c3d22f5ad344990acd81bad1f718fjseward    AT_body_end			= (0x8050|FORM_ADDR)
13038b3131a0c22c3d22f5ad344990acd81bad1f718fjseward};
13048b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
13058b3131a0c22c3d22f5ad344990acd81bad1f718fjseward/* end of enums taken from gdb-6.0 sources */
13065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj#if 0
13077eb7c58d166ac00515ec757dcf9c7b0d177d28c9sewardjvoid ML_(read_debuginfo_dwarf1) (
1308b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj        struct _DebugInfo* di,
13098b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        UChar* dwarf1d, Int dwarf1d_sz,
13108b3131a0c22c3d22f5ad344990acd81bad1f718fjseward        UChar* dwarf1l, Int dwarf1l_sz )
13118b3131a0c22c3d22f5ad344990acd81bad1f718fjseward{
13128b3131a0c22c3d22f5ad344990acd81bad1f718fjseward   UInt   stmt_list;
13138b3131a0c22c3d22f5ad344990acd81bad1f718fjseward   Bool   stmt_list_found;
13148b3131a0c22c3d22f5ad344990acd81bad1f718fjseward   Int    die_offset, die_szb, at_offset;
13158b3131a0c22c3d22f5ad344990acd81bad1f718fjseward   UShort die_kind, at_kind;
13168b3131a0c22c3d22f5ad344990acd81bad1f718fjseward   UChar* at_base;
13171636d33c13958b9c0e7d3059cdd5005746418eb2florian   HChar* src_filename;
13188b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
13198b3131a0c22c3d22f5ad344990acd81bad1f718fjseward   if (0)
13208b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      VG_(printf)("read_debuginfo_dwarf1 ( %p, %d, %p, %d )\n",
13218b3131a0c22c3d22f5ad344990acd81bad1f718fjseward	          dwarf1d, dwarf1d_sz, dwarf1l, dwarf1l_sz );
13228b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
13238b3131a0c22c3d22f5ad344990acd81bad1f718fjseward   /* This loop scans the DIEs. */
13248b3131a0c22c3d22f5ad344990acd81bad1f718fjseward   die_offset = 0;
13258b3131a0c22c3d22f5ad344990acd81bad1f718fjseward   while (True) {
13268b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      if (die_offset >= dwarf1d_sz) break;
13278b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
1328b4dd5b4d16fe556d465fcec53f72e059da1ce511tom      die_szb  = ML_(read_Int)(dwarf1d + die_offset);
1329b4dd5b4d16fe556d465fcec53f72e059da1ce511tom      die_kind = ML_(read_UShort)(dwarf1d + die_offset + 4);
13308b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
13318b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      /* We're only interested in compile_unit DIEs; ignore others. */
13328b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      if (die_kind != TAG_compile_unit) {
13338b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         die_offset += die_szb;
13348b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         continue;
13358b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      }
13368b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
13378b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      if (0)
13388b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         VG_(printf)("compile-unit DIE: offset %d, tag 0x%x, size %d\n",
13398b3131a0c22c3d22f5ad344990acd81bad1f718fjseward                     die_offset, (Int)die_kind, die_szb );
13408b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
13418b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      /* We've got a compile_unit DIE starting at (dwarf1d +
13428b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         die_offset+6).  Try and find the AT_name and AT_stmt_list
13438b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         attributes.  Then, finally, we can read the line number info
13448b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         for this source file. */
13458b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
13468b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      /* The next 3 are set as we find the relevant attrs. */
13478b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      src_filename    = NULL;
13488b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      stmt_list_found = False;
13498b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      stmt_list       = 0;
13508b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
13518b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      /* This loop scans the Attrs inside compile_unit DIEs. */
13528b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      at_base = dwarf1d + die_offset + 6;
13538b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      at_offset = 0;
13548b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      while (True) {
13558b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         if (at_offset >= die_szb-6) break;
13568b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
1357b4dd5b4d16fe556d465fcec53f72e059da1ce511tom         at_kind = ML_(read_UShort)(at_base + at_offset);
13588b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         if (0) VG_(printf)("atoffset %d, attag 0x%x\n",
13598b3131a0c22c3d22f5ad344990acd81bad1f718fjseward                            at_offset, (Int)at_kind );
13608b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         at_offset += 2; /* step over the attribute itself */
13618b3131a0c22c3d22f5ad344990acd81bad1f718fjseward	 /* We have to examine the attribute to figure out its
13628b3131a0c22c3d22f5ad344990acd81bad1f718fjseward            length. */
13638b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         switch (at_kind) {
13648b3131a0c22c3d22f5ad344990acd81bad1f718fjseward            case AT_stmt_list:
13658b3131a0c22c3d22f5ad344990acd81bad1f718fjseward            case AT_language:
13668b3131a0c22c3d22f5ad344990acd81bad1f718fjseward            case AT_sibling:
13678b3131a0c22c3d22f5ad344990acd81bad1f718fjseward               if (at_kind == AT_stmt_list) {
13688b3131a0c22c3d22f5ad344990acd81bad1f718fjseward                  stmt_list_found = True;
1369b4dd5b4d16fe556d465fcec53f72e059da1ce511tom                  stmt_list = ML_(read_Int)(at_base+at_offset);
13708b3131a0c22c3d22f5ad344990acd81bad1f718fjseward               }
13718b3131a0c22c3d22f5ad344990acd81bad1f718fjseward               at_offset += 4; break;
13728b3131a0c22c3d22f5ad344990acd81bad1f718fjseward            case AT_high_pc:
13738b3131a0c22c3d22f5ad344990acd81bad1f718fjseward            case AT_low_pc:
13748b3131a0c22c3d22f5ad344990acd81bad1f718fjseward               at_offset += sizeof(void*); break;
13758b3131a0c22c3d22f5ad344990acd81bad1f718fjseward            case AT_name:
13768b3131a0c22c3d22f5ad344990acd81bad1f718fjseward            case AT_producer:
13778b3131a0c22c3d22f5ad344990acd81bad1f718fjseward            case AT_comp_dir:
13788b3131a0c22c3d22f5ad344990acd81bad1f718fjseward               /* Zero terminated string, step over it. */
13798b3131a0c22c3d22f5ad344990acd81bad1f718fjseward               if (at_kind == AT_name)
13801636d33c13958b9c0e7d3059cdd5005746418eb2florian                 src_filename = (HChar *)(at_base + at_offset);
13818b3131a0c22c3d22f5ad344990acd81bad1f718fjseward               while (at_offset < die_szb-6 && at_base[at_offset] != 0)
13828b3131a0c22c3d22f5ad344990acd81bad1f718fjseward                  at_offset++;
13838b3131a0c22c3d22f5ad344990acd81bad1f718fjseward               at_offset++;
13848b3131a0c22c3d22f5ad344990acd81bad1f718fjseward               break;
13858b3131a0c22c3d22f5ad344990acd81bad1f718fjseward            default:
13868b3131a0c22c3d22f5ad344990acd81bad1f718fjseward               VG_(printf)("Unhandled DWARF-1 attribute 0x%x\n",
13878b3131a0c22c3d22f5ad344990acd81bad1f718fjseward                           (Int)at_kind );
13888b3131a0c22c3d22f5ad344990acd81bad1f718fjseward               VG_(core_panic)("Unhandled DWARF-1 attribute");
13898b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         } /* switch (at_kind) */
13908b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      } /* looping over attributes */
13918b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
13928b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      /* So, did we find the required stuff for a line number table in
13938b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         this DIE?  If yes, read it. */
13948b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      if (stmt_list_found /* there is a line number table */
13958b3131a0c22c3d22f5ad344990acd81bad1f718fjseward          && src_filename != NULL /* we know the source filename */
13968b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         ) {
13978b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         /* Table starts:
13988b3131a0c22c3d22f5ad344990acd81bad1f718fjseward               Length:
13998b3131a0c22c3d22f5ad344990acd81bad1f718fjseward                  4 bytes, includes the entire table
14008b3131a0c22c3d22f5ad344990acd81bad1f718fjseward               Base address:
14018b3131a0c22c3d22f5ad344990acd81bad1f718fjseward                  unclear (4? 8?), assuming native pointer size here.
14028b3131a0c22c3d22f5ad344990acd81bad1f718fjseward            Then a sequence of triples
14038b3131a0c22c3d22f5ad344990acd81bad1f718fjseward               (source line number -- 32 bits
14048b3131a0c22c3d22f5ad344990acd81bad1f718fjseward                source line column -- 16 bits
14058b3131a0c22c3d22f5ad344990acd81bad1f718fjseward                address delta -- 32 bits)
14068b3131a0c22c3d22f5ad344990acd81bad1f718fjseward	 */
14078b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         Addr   base;
14088b3131a0c22c3d22f5ad344990acd81bad1f718fjseward	 Int    len;
14091636d33c13958b9c0e7d3059cdd5005746418eb2florian         HChar* curr_filenm;
14108b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         UChar* ptr;
14118b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         UInt   prev_line, prev_delta;
14128b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
1413b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         curr_filenm = ML_(addStr) ( di, src_filename, -1 );
14148b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         prev_line = prev_delta = 0;
14158b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
14168b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         ptr = dwarf1l + stmt_list;
1417b4dd5b4d16fe556d465fcec53f72e059da1ce511tom         len  = ML_(read_Int)(ptr);  ptr += sizeof(Int);
1418ba4ce2f444ed31687d539a081b06dd76cdd4a39ctom         base = ML_(read_Addr)(ptr); ptr += sizeof(void*);
14198b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         len -= (sizeof(Int) + sizeof(void*));
14208b3131a0c22c3d22f5ad344990acd81bad1f718fjseward         while (len > 0) {
14218b3131a0c22c3d22f5ad344990acd81bad1f718fjseward            UInt   line;
14228b3131a0c22c3d22f5ad344990acd81bad1f718fjseward            UShort col;
14238b3131a0c22c3d22f5ad344990acd81bad1f718fjseward            UInt   delta;
1424b4dd5b4d16fe556d465fcec53f72e059da1ce511tom            line = ML_(read_UInt)(ptr);    ptr += sizeof(UInt);
1425b4dd5b4d16fe556d465fcec53f72e059da1ce511tom            col  = ML_(read_UShort)(ptr);  ptr += sizeof(UShort);
1426b4dd5b4d16fe556d465fcec53f72e059da1ce511tom            delta = ML_(read_UInt)(ptr);   ptr += sizeof(UInt);
14278b3131a0c22c3d22f5ad344990acd81bad1f718fjseward	    if (0) VG_(printf)("line %d, col %d, delta %d\n",
14288b3131a0c22c3d22f5ad344990acd81bad1f718fjseward                               line, (Int)col, delta );
14298b3131a0c22c3d22f5ad344990acd81bad1f718fjseward            len -= (sizeof(UInt) + sizeof(UShort) + sizeof(UInt));
14308b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
14318b3131a0c22c3d22f5ad344990acd81bad1f718fjseward	    if (delta > 0 && prev_line > 0) {
14328b3131a0c22c3d22f5ad344990acd81bad1f718fjseward	       if (0) VG_(printf) ("     %d  %d-%d\n",
14338b3131a0c22c3d22f5ad344990acd81bad1f718fjseward                                   prev_line, prev_delta, delta-1);
1434b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	       ML_(addLineInfo) ( di, curr_filenm, NULL,
14358b3131a0c22c3d22f5ad344990acd81bad1f718fjseward		 	          base + prev_delta, base + delta,
14368b3131a0c22c3d22f5ad344990acd81bad1f718fjseward			          prev_line, 0 );
14378b3131a0c22c3d22f5ad344990acd81bad1f718fjseward	    }
14388b3131a0c22c3d22f5ad344990acd81bad1f718fjseward	    prev_line = line;
14398b3131a0c22c3d22f5ad344990acd81bad1f718fjseward	    prev_delta = delta;
14408b3131a0c22c3d22f5ad344990acd81bad1f718fjseward	 }
14418b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      }
14428b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
1443ad4e979f408239dabbaae955d8ffcb84a51a5c85florian      /* Move on the next DIE. */
14448b3131a0c22c3d22f5ad344990acd81bad1f718fjseward      die_offset += die_szb;
14458b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
14468b3131a0c22c3d22f5ad344990acd81bad1f718fjseward   } /* Looping over DIEs */
14478b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
14488b3131a0c22c3d22f5ad344990acd81bad1f718fjseward}
14495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj#endif
14508b3131a0c22c3d22f5ad344990acd81bad1f718fjseward
14515c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj/*------------------------------------------------------------*/
14525c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj/*--- Read call-frame info from an .eh_frame section       ---*/
14535c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj/*------------------------------------------------------------*/
14545c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
1455461d6c69908dade34a67afe34b09f54cce74d5a3sewardj/* Sources of info:
1456461d6c69908dade34a67afe34b09f54cce74d5a3sewardj
1457461d6c69908dade34a67afe34b09f54cce74d5a3sewardj   The DWARF3 spec, available from http://www.dwarfstd.org/Download.php
1458461d6c69908dade34a67afe34b09f54cce74d5a3sewardj
1459461d6c69908dade34a67afe34b09f54cce74d5a3sewardj   This describes how to read CFA data from .debug_frame sections.
1460461d6c69908dade34a67afe34b09f54cce74d5a3sewardj   So as to maximise everybody's annoyance and confusion, .eh_frame
1461461d6c69908dade34a67afe34b09f54cce74d5a3sewardj   sections are almost the same as .debug_frame sections, but differ
1462461d6c69908dade34a67afe34b09f54cce74d5a3sewardj   in a few subtle and ill documented but important aspects.
1463461d6c69908dade34a67afe34b09f54cce74d5a3sewardj
1464461d6c69908dade34a67afe34b09f54cce74d5a3sewardj   Generic ELF Specification, sections 7.5 (DWARF Extensions) and 7.6
1465461d6c69908dade34a67afe34b09f54cce74d5a3sewardj   (Exception Frames), available from
1466461d6c69908dade34a67afe34b09f54cce74d5a3sewardj
1467461d6c69908dade34a67afe34b09f54cce74d5a3sewardj   http://www.linux-foundation.org/spec/book/ELF-generic/ELF-generic.html
1468461d6c69908dade34a67afe34b09f54cce74d5a3sewardj
1469461d6c69908dade34a67afe34b09f54cce74d5a3sewardj   This really does describe .eh_frame, at least the aspects that
1470461d6c69908dade34a67afe34b09f54cce74d5a3sewardj   differ from standard DWARF3.  It's better than guessing, and
1471461d6c69908dade34a67afe34b09f54cce74d5a3sewardj   (marginally) more fun than reading the gdb source code.
1472461d6c69908dade34a67afe34b09f54cce74d5a3sewardj*/
1473461d6c69908dade34a67afe34b09f54cce74d5a3sewardj
147455022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj/* Useful info ..
147555022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
147655022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj   In general:
147755022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj   gdb-6.3/gdb/dwarf2-frame.c
147855022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
147955022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj   gdb-6.3/gdb/i386-tdep.c:
148055022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
148155022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj   DWARF2/GCC uses the stack address *before* the function call as a
148255022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj   frame's CFA.  [jrs: I presume this means %esp before the call as
148355022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj   the CFA].
148455022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
148555022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj   JRS: on amd64, the dwarf register numbering is, as per
1486b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   gdb-6.3/gdb/amd64-tdep.c and also amd64-abi-0.98.pdf:
148755022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
148855022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj      0    1    2    3    4    5    6    7
148955022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj      RAX  RDX  RCX  RBX  RSI  RDI  RBP  RSP
149055022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
149155022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj      8  ...  15
149255022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj      R8 ... R15
149355022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
149455022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj      16 is the return address (RIP)
149594ef4a4208c19994029f8975649e2f762c028e32sewardj      "The table defines Return Address to have a register number,
149694ef4a4208c19994029f8975649e2f762c028e32sewardj      even though the address is stored in 0(%rsp) and not in a
149794ef4a4208c19994029f8975649e2f762c028e32sewardj      physical register."
149894ef4a4208c19994029f8975649e2f762c028e32sewardj
149994ef4a4208c19994029f8975649e2f762c028e32sewardj      17   ...   24
150094ef4a4208c19994029f8975649e2f762c028e32sewardj      XMM0 ... XMM7
150194ef4a4208c19994029f8975649e2f762c028e32sewardj
150294ef4a4208c19994029f8975649e2f762c028e32sewardj      25   ...    32
150394ef4a4208c19994029f8975649e2f762c028e32sewardj      XMM8 ... XMM15
150494ef4a4208c19994029f8975649e2f762c028e32sewardj
150594ef4a4208c19994029f8975649e2f762c028e32sewardj      33   ...   40
150694ef4a4208c19994029f8975649e2f762c028e32sewardj      ST0  ...  ST7
150794ef4a4208c19994029f8975649e2f762c028e32sewardj
150894ef4a4208c19994029f8975649e2f762c028e32sewardj      41   ...   48
150994ef4a4208c19994029f8975649e2f762c028e32sewardj      MM0  ...  MM7
151094ef4a4208c19994029f8975649e2f762c028e32sewardj
151194ef4a4208c19994029f8975649e2f762c028e32sewardj      49                  RFLAGS
151294ef4a4208c19994029f8975649e2f762c028e32sewardj      50,51,52,53,54,55   ES,CS,SS,DS,FS,GS
151394ef4a4208c19994029f8975649e2f762c028e32sewardj      58                  FS.BASE  (what's that?)
151494ef4a4208c19994029f8975649e2f762c028e32sewardj      59                  GS.BASE  (what's that?)
151594ef4a4208c19994029f8975649e2f762c028e32sewardj      62                  TR (task register)
151694ef4a4208c19994029f8975649e2f762c028e32sewardj      63                  LDTR (LDT register)
151794ef4a4208c19994029f8975649e2f762c028e32sewardj      64                  MXCSR
151894ef4a4208c19994029f8975649e2f762c028e32sewardj      65                  FCW (x87 control word)
151994ef4a4208c19994029f8975649e2f762c028e32sewardj      66                  FSW (x86 status word)
152055022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
152155022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj   On x86 I cannot find any documentation.  It _appears_ to be the
152255022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj   actual instruction encoding, viz:
152355022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
152455022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj      0    1    2    3    4    5    6    7
152555022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj      EAX  ECX  EDX  EBX  ESP  EBP  ESI  EDI
152655022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
152755022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj      8 is the return address (EIP) */
152855022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
152955022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
15301936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj/* Comments re DW_CFA_set_loc, 16 Nov 06.
15311936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj
15321936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   JRS:
15331936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   Someone recently sent me a libcrypto.so.0.9.8 as distributed with
15341936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   Ubuntu of some flavour, compiled with gcc 4.1.2 on amd64.  It
15351936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   causes V's CF reader to complain a lot:
15361936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj
15371936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   >> --19976-- DWARF2 CFI reader: unhandled CFI instruction 0:24
15381936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   >> --19976-- DWARF2 CFI reader: unhandled CFI instruction 0:24
15391936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   >> --19976-- DWARF2 CFI reader: unhandled CFI instruction 0:24
15401936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   >> --19976-- DWARF2 CFI reader: unhandled CFI instruction 0:24
15411936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   >> --19976-- DWARF2 CFI reader: unhandled CFI instruction 0:48
15421936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   >> --19976-- DWARF2 CFI reader: unhandled CFI instruction 0:24
15431936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj
15441936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   After chasing this around a bit it seems that the CF bytecode
15451936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   parser lost sync at a DW_CFA_set_loc, which has a single argument
15461936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   denoting an address.
15471936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj
15481936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   As it stands that address is extracted by read_Addr().  On amd64
15491936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   that just fetches 8 bytes regardless of anything else.
15501936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj
15511936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   read_encoded_Addr() is more sophisticated.  This appears to take
15521936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   into account some kind of encoding flag.  When I replace the uses
15531936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   of read_Addr by read_encoded_Addr for DW_CFA_set_loc, the
15541936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   complaints go away, there is no loss of sync, and the parsed CF
15551936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   instructions are the same as shown by readelf --debug-dump=frames.
15561936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj
15571936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   So it seems a plausible fix.  The problem is I looked in the DWARF3
15581936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   spec and completely failed to figure out whether or not the arg to
15591936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   DW_CFA_set_loc is supposed to be encoded in a way suitable for
15601936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   read_encoded_Addr, nor for that matter any description of what it
15611936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   is that read_encoded_Addr is really decoding.
15621936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj
15631936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   TomH:
15641936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   The problem is that the encoding is not standard - the eh_frame
15651936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   section uses the same encoding as the dwarf_frame section except
15661936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   for a few small changes, and this is one of them. So this is not
15671936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   something the DWARF standard covers.
15681936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj
15691936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   There is an augmentation string to indicate what is going on though
15701936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   so that programs can recognise it.
15711936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj
15721936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   What we are doing seems to match what gdb 6.5 and libdwarf 20060614
15731936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   do though. I'm not sure about readelf though.
15741936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj
15751936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   (later): Well dwarfdump barfs on it:
15761936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj
15771936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj      dwarfdump ERROR:  dwarf_get_fde_info_for_reg:
15781936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj                        DW_DLE_DF_FRAME_DECODING_ERROR(193) (193)
15791936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj
15801936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   I've looked at binutils as well now, and the code in readelf agrees
15811936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   with your patch - ie it treats set_loc as having an encoded address
15821936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   if there is a zR augmentation indicating an encoding.
15831936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj
15841936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   Quite why gdb and libdwarf don't understand this is an interesting
15851936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   question...
15861936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj
15871936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   Final outcome: all uses of read_Addr were replaced by
15881936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   read_encoded_Addr.  A new type AddressDecodingInfo was added to
15891936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   make it relatively clean to plumb through the extra info needed by
15901936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   read_encoded_Addr.
15911936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj*/
15921936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj
15933891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj/* More badness re address encoding, 12 Jan 07.
15943891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
15953891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   Most gcc provided CIEs have a "zR" augmentation, which means they
15963891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   supply their own address encoding, and that works fine.  However,
15973891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   some icc9 supplied CIEs have no augmentation, which means they use
15983891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   the default_Addr_encoding().  That says to use a machine-word sized
15993891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   value, literally unmodified.
16003891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
16013891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   Since .so's are, in general, relocated when loaded, having absolute
16023891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   addresses in the CFI data makes no sense when read_encoded_Addr is
16033891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   used to find the initial location for a FDE.  The resulting saga:
16043891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
16053891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   TomH:
16063891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   > I'm chasing a stack backtrace failure for an amd64 .so which was
16073891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   > created I believe by icc 9.1.  After a while I wound up looking at
16083891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   > this: (readdwarf.c)
16093891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   >
16103891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   >   5083        tom static UChar default_Addr_encoding ( void )
16113891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   >   3584        tom {
16123891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   >   3584        tom    switch (sizeof(Addr)) {
16133891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   >   3584        tom       case 4: return DW_EH_PE_udata4;
16143891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   >   3584        tom       case 8: return DW_EH_PE_udata8;
16153891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   >   3584        tom       default: vg_assert(0);
16163891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   >   3584        tom    }
16173891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   >   3584        tom }
16183891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   >
16193891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   > If a CIE does not have an "augmentation string" (typically "zR") then
16203891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   > addresses are decoded as described by default_Addr_encoding.  If there
16213891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   > is an 'R' in the augmentation string then the encoding to use
16223891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   > is specified by the CIE itself, which works fine with GCC compiled code
16233891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   > since that always appears to specify zR.
16243891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
16253891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   Correct.
16263891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
16273891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   > Problem is this .so has no augmentation string and so uses the
16283891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   > default encoding, viz DW_EH_PE_udata8.  That appears to mean
16293891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   > "read a 64 bit number" and use that as-is (for the starting value
16303891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   > of the program counter when running the CFA program).
16313891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
16323891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   Strictly speaking the default is DW_EH_PE_absptr, but that amounts
16333891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   to either udata4 or udata8 depending on the platform's pointer size
16343891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   which is a shortcut I used.
16353891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
16363891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   > For this .so that gives nonsense (very small) PCs which are later
16373891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   > rejected by the sanity check which ensures PC ranges fall inside
16383891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   > the mapped text segment.  It seems like the .so expects to have the
16393891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   > start VMA of the text segment added on.  This would correspond to
16403891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   >
16413891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   >   static UChar default_Addr_encoding ( void )
16423891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   >   {
16433891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   >      switch (sizeof(Addr)) {
16443891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   >         case 4: return DW_EH_PE_textrel + DW_EH_PE_udata4;
16453891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   >         case 8: return DW_EH_PE_textrel + DW_EH_PE_udata8;
16463891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   >         default: vg_assert(0);
16473891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   >      }
16483891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   >   }
16493891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
16503891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   The problem you're seeing is that you have absolute pointers inside
16513891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   a shared library, which obviously makes little sense on the face of
16523891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   things as how would the linker know where the library will be
16533891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   loaded?
16543891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
16553891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   The answer of course is that it doesn't, so if it points absolute
16563891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   pointers in the frame unwind data is has to include relocations for
16573891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   them, and I'm betting that if you look at the relocations in the
16583891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   library you will there are some for that data.
16593891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
16603891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   That is fine of course when ld.so maps the library - it will
16613891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   relocate the eh_frame data as it maps it (or prelinking will
16623891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   already have done so) and when the g++ exception code kicks in and
16633891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   unwinds the stack it will see relocated data.
16643891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
16653891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   We of course are mapping the section from the ELF file ourselves
16663891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   and are not applying the relocations, hence the problem you are
16673891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   seeing.
16683891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
16693891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   Strictly speaking we should apply the relocations but the cheap
16703891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   solution is essentially to do what you've done - strictly speaking
16713891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   you should adjust by the difference between the address the library
16723891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   was linked for and the address it has been loaded at, but a shared
16733891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   library will normally be linked for address zero I believe. It's
16743891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   possible that prelinking might change that though?
16753891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
16763891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   JRS:
16773891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   That all syncs with what I am seeing.
16783891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
16793891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   So what I am inclined to do is:
16803891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
16813891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   - Leave default_Addr_encoding as it is
16823891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
16833891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   - Change read_encoded_Addr's handling of "case DW_EH_PE_absptr" so
16843891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj     it sets base to, as you say, the difference between the address
16853891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj     the library was linked for and the address it has been loaded at
16863891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj     (== the SegInfo's text_bias)
16873891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
16883891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   Does that sound sane?  I think it should even handle the prelinked
16893891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   case.
16903891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
16913891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   (JRS, later)
16923891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
16933891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   Hmm.  Plausible as it sounds, it doesn't work.  It now produces
16943891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   bogus backtraces for locations inside the (statically linked)
16953891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   memcheck executable.
16963891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
16973891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   Besides, there are a couple of other places where read_encoded_Addr
16983891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   is used -- one of which is used to establish the length of the
16993891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   address range covered by the current FDE:
17003891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
17013891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj         fde_arange = read_encoded_Addr(&nbytes, &adi, data);
17023891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
17033891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   and it doesn't seem to make any sense for read_encoded_Addr to add
17043891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   on the text segment bias in that context.  The DWARF3 spec says
17053891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   that both the initial_location and address_range (length) fields
17063891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   are encoded the same way ("target address"), so it is unclear at
17073891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   what stage in the process it would be appropriate to relocate the
17083891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   former but not the latter.
17093891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
17103891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   One unprincipled kludge that does work is the following: just
17113891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   before handing one of the address range fragments off to
17123891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   ML_(addDiCfSI) for permanent storage, check its start address.  If
17133891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   that is very low (less than 2 M), and is far below the mapped text
17143891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   segment, and adding the text bias would move the fragment entirely
17153891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   inside the mapped text segment, then do so.  A kind of kludged
17163891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   last-minute relocation, if you like.
17173891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
17183891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   12 Jan 07: committing said kludge (see kludge_then_addDiCfSI).  If
17193891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   the situation clarifies, it can easily enough be backed out and
17203891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj   replaced by a better fix.
17213891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj*/
17223891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
172355022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj/* --------------- Decls --------------- */
172435165537cfa2da18220e55e23f21228c1e2591fesewardj
17258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#if defined(VGP_x86_linux) || defined(VGP_x86_solaris)
172614b278bf9deac394f33fe6890195f84391891dc1njn#  define FP_REG         5
172714b278bf9deac394f33fe6890195f84391891dc1njn#  define SP_REG         4
172814b278bf9deac394f33fe6890195f84391891dc1njn#  define RA_REG_DEFAULT 8
17298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#elif defined(VGP_amd64_linux) || defined(VGP_amd64_solaris)
173014b278bf9deac394f33fe6890195f84391891dc1njn#  define FP_REG         6
173114b278bf9deac394f33fe6890195f84391891dc1njn#  define SP_REG         7
173214b278bf9deac394f33fe6890195f84391891dc1njn#  define RA_REG_DEFAULT 16
173385665ca6fa29dd64754dabe50eb98f25896e752acerion#elif defined(VGP_ppc32_linux)
173485665ca6fa29dd64754dabe50eb98f25896e752acerion#  define FP_REG         1
173585665ca6fa29dd64754dabe50eb98f25896e752acerion#  define SP_REG         1
17363c9cf3442185b5891e15450d6e3058aeff6796fetom#  define RA_REG_DEFAULT 65
1737cae0cc22b83ffb260ee8379e92099c5a701944cbcarll#elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
17382c48c7b0a453d32375a4df17e153011b797ef28csewardj#  define FP_REG         1
17392c48c7b0a453d32375a4df17e153011b797ef28csewardj#  define SP_REG         1
17403c9cf3442185b5891e15450d6e3058aeff6796fetom#  define RA_REG_DEFAULT 65
17413026f71684a930286186aa10fef266c304672e8fsewardj#elif defined(VGP_arm_linux)
17423026f71684a930286186aa10fef266c304672e8fsewardj#  define FP_REG         12
17433026f71684a930286186aa10fef266c304672e8fsewardj#  define SP_REG         13
1744821283b2110420321fd3f60afcc799b287788c68sewardj#  define RA_REG_DEFAULT 14
1745f0c1250e324f6684757c6a15545366447ef1d64fsewardj#elif defined(VGP_arm64_linux)
1746821283b2110420321fd3f60afcc799b287788c68sewardj#  define FP_REG         29
1747821283b2110420321fd3f60afcc799b287788c68sewardj#  define SP_REG         31
1748821283b2110420321fd3f60afcc799b287788c68sewardj#  define RA_REG_DEFAULT 30
1749f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(VGP_x86_darwin)
1750f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  define FP_REG         5
1751f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  define SP_REG         4
1752f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  define RA_REG_DEFAULT 8
1753f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#elif defined(VGP_amd64_darwin)
1754f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  define FP_REG         6
1755f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  define SP_REG         7
1756f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#  define RA_REG_DEFAULT 16
1757b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#elif defined(VGP_s390x_linux)
1758b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#  define FP_REG         11    // sometimes s390 has a frame pointer in r11
1759b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#  define SP_REG         15    // stack is always r15
1760b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#  define RA_REG_DEFAULT 14    // the return address is in r14
17615db15403e889d4db339b342bc2a824ef0bfaa654sewardj#elif defined(VGP_mips32_linux)
17625db15403e889d4db339b342bc2a824ef0bfaa654sewardj#  define FP_REG         30
17635db15403e889d4db339b342bc2a824ef0bfaa654sewardj#  define SP_REG         29
17645db15403e889d4db339b342bc2a824ef0bfaa654sewardj#  define RA_REG_DEFAULT 31
17654df0bfc0614379192c780c944415dc420d9cfe8epetarj#elif defined(VGP_mips64_linux)
17664df0bfc0614379192c780c944415dc420d9cfe8epetarj#  define FP_REG         30
17674df0bfc0614379192c780c944415dc420d9cfe8epetarj#  define SP_REG         29
17684df0bfc0614379192c780c944415dc420d9cfe8epetarj#  define RA_REG_DEFAULT 31
1769112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#elif defined(VGP_tilegx_linux)
1770112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#  define FP_REG         52
1771112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#  define SP_REG         54
1772112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#  define RA_REG_DEFAULT 55
177314b278bf9deac394f33fe6890195f84391891dc1njn#else
1774b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj#  error "Unknown platform"
17752fd38908d48d2a081e59ae67ffdb76b7f611ee8etom#endif
177635165537cfa2da18220e55e23f21228c1e2591fesewardj
177787a1fa5fd47ba309d196e5c8127bf2d98c8bfa65sewardj/* The number of regs we are prepared to unwind.  The number for
177887a1fa5fd47ba309d196e5c8127bf2d98c8bfa65sewardj   arm-linux (320) seems ludicrously high, but the ARM IHI 0040A page
177987a1fa5fd47ba309d196e5c8127bf2d98c8bfa65sewardj   7 (DWARF for the ARM Architecture) specifies that values up to 320
178087a1fa5fd47ba309d196e5c8127bf2d98c8bfa65sewardj   might exist, for Neon/VFP-v3. */
1781cae0cc22b83ffb260ee8379e92099c5a701944cbcarll#if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
1782cae0cc22b83ffb260ee8379e92099c5a701944cbcarll     || defined(VGP_ppc64le_linux) || defined(VGP_mips32_linux) \
1783cae0cc22b83ffb260ee8379e92099c5a701944cbcarll     || defined(VGP_mips64_linux)
17843c9cf3442185b5891e15450d6e3058aeff6796fetom# define N_CFI_REGS 72
1785112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#elif defined(VGP_arm_linux) || defined(VGP_tilegx_linux)
178687a1fa5fd47ba309d196e5c8127bf2d98c8bfa65sewardj# define N_CFI_REGS 320
1787821283b2110420321fd3f60afcc799b287788c68sewardj#elif defined(VGP_arm64_linux)
1788821283b2110420321fd3f60afcc799b287788c68sewardj# define N_CFI_REGS 128
17893c9cf3442185b5891e15450d6e3058aeff6796fetom#else
17903c9cf3442185b5891e15450d6e3058aeff6796fetom# define N_CFI_REGS 20
17913c9cf3442185b5891e15450d6e3058aeff6796fetom#endif
17925c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
17935c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj/* Instructions for the automaton */
17945c638c2bda665e232ecf62b5443c93c3d6b7e06asewardjenum dwarf_cfa_primary_ops
17955c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj  {
17965c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj    DW_CFA_use_secondary = 0,
17975c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj    DW_CFA_advance_loc   = 1,
17985c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj    DW_CFA_offset        = 2,
17995c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj    DW_CFA_restore       = 3
18005c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj  };
18015c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
18025c638c2bda665e232ecf62b5443c93c3d6b7e06asewardjenum dwarf_cfa_secondary_ops
18035c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj  {
1804325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj    DW_CFA_nop                = 0x00,
1805325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj    DW_CFA_set_loc            = 0x01,
1806325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj    DW_CFA_advance_loc1       = 0x02,
1807325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj    DW_CFA_advance_loc2       = 0x03,
1808325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj    DW_CFA_advance_loc4       = 0x04,
1809325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj    DW_CFA_offset_extended    = 0x05,
1810325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj    DW_CFA_restore_extended   = 0x06,
1811325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj    DW_CFA_undefined          = 0x07,
1812325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj    DW_CFA_same_value         = 0x08,
1813325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj    DW_CFA_register           = 0x09,
1814325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj    DW_CFA_remember_state     = 0x0a,
1815325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj    DW_CFA_restore_state      = 0x0b,
1816325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj    DW_CFA_def_cfa            = 0x0c,
1817325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj    DW_CFA_def_cfa_register   = 0x0d,
1818325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj    DW_CFA_def_cfa_offset     = 0x0e,
18191e601fe35a89c584cb028b92b000a89d573181c8sewardj    DW_CFA_def_cfa_expression = 0x0f, /* DWARF3 only */
18201e601fe35a89c584cb028b92b000a89d573181c8sewardj    DW_CFA_expression         = 0x10, /* DWARF3 only */
1821325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj    DW_CFA_offset_extended_sf = 0x11, /* DWARF3 only */
1822d69222cb20119a410b777665e16873a2391f9344sewardj    DW_CFA_def_cfa_sf         = 0x12, /* DWARF3 only */
1823ab30d209064d9ed84d8a218e627f5a1345e9d30bsewardj    DW_CFA_def_cfa_offset_sf  = 0x13, /* DWARF3 only */
1824d69222cb20119a410b777665e16873a2391f9344sewardj    DW_CFA_val_offset         = 0x14, /* DWARF3 only */
1825d69222cb20119a410b777665e16873a2391f9344sewardj    DW_CFA_val_offset_sf      = 0x15, /* DWARF3 only */
1826d69222cb20119a410b777665e16873a2391f9344sewardj    DW_CFA_val_expression     = 0x16, /* DWARF3 only */
1827325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj    DW_CFA_lo_user            = 0x1c,
18280cd717757871b2bb53228dae66a28d2b88f18e36sewardj    DW_CFA_GNU_window_save    = 0x2d, /* GNU extension */
18290cd717757871b2bb53228dae66a28d2b88f18e36sewardj    DW_CFA_GNU_args_size      = 0x2e, /* GNU extension */
1830d69222cb20119a410b777665e16873a2391f9344sewardj    DW_CFA_GNU_negative_offset_extended = 0x2f, /* GNU extension */
18318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj    DW_CFA_ORCL_arg_loc       = 0x30, /* Oracle extension */
1832325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj    DW_CFA_hi_user            = 0x3f
18335c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj  };
18345c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
18352fd38908d48d2a081e59ae67ffdb76b7f611ee8etom#define DW_EH_PE_absptr		0x00
18362fd38908d48d2a081e59ae67ffdb76b7f611ee8etom#define DW_EH_PE_omit		0xff
18372fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
18382fd38908d48d2a081e59ae67ffdb76b7f611ee8etom#define DW_EH_PE_uleb128	0x01
18392fd38908d48d2a081e59ae67ffdb76b7f611ee8etom#define DW_EH_PE_udata2		0x02
18402fd38908d48d2a081e59ae67ffdb76b7f611ee8etom#define DW_EH_PE_udata4		0x03
18412fd38908d48d2a081e59ae67ffdb76b7f611ee8etom#define DW_EH_PE_udata8		0x04
18422fd38908d48d2a081e59ae67ffdb76b7f611ee8etom#define DW_EH_PE_sleb128	0x09
18432fd38908d48d2a081e59ae67ffdb76b7f611ee8etom#define DW_EH_PE_sdata2		0x0A
18442fd38908d48d2a081e59ae67ffdb76b7f611ee8etom#define DW_EH_PE_sdata4		0x0B
18452fd38908d48d2a081e59ae67ffdb76b7f611ee8etom#define DW_EH_PE_sdata8		0x0C
18462fd38908d48d2a081e59ae67ffdb76b7f611ee8etom#define DW_EH_PE_signed		0x08
18472fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
18482fd38908d48d2a081e59ae67ffdb76b7f611ee8etom#define DW_EH_PE_pcrel		0x10
18492fd38908d48d2a081e59ae67ffdb76b7f611ee8etom#define DW_EH_PE_textrel	0x20
18502fd38908d48d2a081e59ae67ffdb76b7f611ee8etom#define DW_EH_PE_datarel	0x30
18512fd38908d48d2a081e59ae67ffdb76b7f611ee8etom#define DW_EH_PE_funcrel	0x40
18522fd38908d48d2a081e59ae67ffdb76b7f611ee8etom#define DW_EH_PE_aligned	0x50
18532fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
18542fd38908d48d2a081e59ae67ffdb76b7f611ee8etom#define DW_EH_PE_indirect	0x80
18552fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
18565c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
185755022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj/* RegRule and UnwindContext are used temporarily to do the unwinding.
1858726baecdd1d6614ef65a8d84217cfccde951be66sewardj   The result is then summarised into a sequence of CfiSIs, if
1859726baecdd1d6614ef65a8d84217cfccde951be66sewardj   possible.  UnwindContext effectively holds the state of the
1860726baecdd1d6614ef65a8d84217cfccde951be66sewardj   abstract machine whilst it is running.
186172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
186272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   The CFA can either be a signed offset from a register,
186372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   or an expression:
186472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
186572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   CFA = cfa_reg + cfa_off   when UnwindContext.cfa_is_regoff==True
186672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj       | [[ cfa_expr_id ]]
186772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
186872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   When .cfa_is_regoff == True,  cfa_expr_id must be zero
186972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   When .cfa_is_regoff == False, cfa_reg must be zero
187072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj                                 and cfa_off must be zero
187172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
187272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   RegRule describes, for each register, how to get its
187372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   value in the previous frame, where 'cfa' denotes the cfa
187472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   for the frame as a whole:
187572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
187672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   RegRule = RR_Undef          -- undefined
187772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj           | RR_Same           -- same as in previous frame
187872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj           | RR_CFAOff    arg  -- is at * ( cfa + arg )
187972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj           | RR_CFAValOff arg  -- is ( cfa + arg )
188072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj           | RR_Reg       arg  -- is in register 'arg'
188172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj           | RR_Expr      arg  -- is at * [[ arg ]]
188272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj           | RR_ValExpr   arg  -- is [[ arg ]]
188372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj           | RR_Arch           -- dunno
188472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
188519dc88f90d0e19a1463797dd99f6792a42f961d3sewardj   Note that RR_Expr is redundant since the same can be represented
188619dc88f90d0e19a1463797dd99f6792a42f961d3sewardj   using RR_ValExpr with an explicit dereference (CfiExpr_Deref) at
188719dc88f90d0e19a1463797dd99f6792a42f961d3sewardj   the outermost level.
188819dc88f90d0e19a1463797dd99f6792a42f961d3sewardj
188972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   All expressions are stored in exprs in the containing
189072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   UnwindContext.  Since the UnwindContext gets reinitialised for each
189172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   new FDE, summarise_context needs to copy out any expressions it
189272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   wants to keep into the cfsi_exprs field of the containing SegInfo.
1893726baecdd1d6614ef65a8d84217cfccde951be66sewardj*/
18945c638c2bda665e232ecf62b5443c93c3d6b7e06asewardjtypedef
18955c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   struct {
189672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      enum { RR_Undef, RR_Same, RR_CFAOff, RR_CFAValOff,
189719dc88f90d0e19a1463797dd99f6792a42f961d3sewardj             RR_Reg, /*RR_Expr,*/ RR_ValExpr, RR_Arch } tag;
189872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      /* meaning:  int offset for CFAoff/CFAValOff
189972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj                   reg # for Reg
190072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj                   expr index for Expr/ValExpr */
190172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      Int arg;
19025c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   }
19035c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   RegRule;
19045c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
19053297124fa2116737066ac3cd709f18fdd5405163florianstatic void ppRegRule ( const XArray* exprs, const RegRule* rrule )
190655022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj{
190772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   vg_assert(exprs);
190872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   switch (rrule->tag) {
190972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      case RR_Undef:     VG_(printf)("u  "); break;
191072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      case RR_Same:      VG_(printf)("s  "); break;
191172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      case RR_CFAOff:    VG_(printf)("c%d ", rrule->arg); break;
191272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      case RR_CFAValOff: VG_(printf)("v%d ", rrule->arg); break;
191372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      case RR_Reg:       VG_(printf)("r%d ", rrule->arg); break;
191472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      case RR_ValExpr:   VG_(printf)("ve{");
191572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj                         ML_(ppCfiExpr)( exprs, rrule->arg );
191672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj                         VG_(printf)("} ");
191772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj                         break;
191872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      case RR_Arch:      VG_(printf)("a  "); break;
191972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      default:           VG_(core_panic)("ppRegRule");
192055022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj   }
192155022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj}
192255022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
192355022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
19243d026b18e0b41e5f13336f1997054f56cbd89da0sewardj/* Size of the stack of register unwind rules.  This is only
19253d026b18e0b41e5f13336f1997054f56cbd89da0sewardj   exceedingly rarely used, so a stack of size 1 should actually work
19263d026b18e0b41e5f13336f1997054f56cbd89da0sewardj   with almost all compiler-generated CFA. */
19273d026b18e0b41e5f13336f1997054f56cbd89da0sewardj#define N_RR_STACK 4
19283d026b18e0b41e5f13336f1997054f56cbd89da0sewardj
19295c638c2bda665e232ecf62b5443c93c3d6b7e06asewardjtypedef
19305c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   struct {
19315410cfd1cc18617076b8c7f41d837bdc90117d38sewardj      /* Read-only fields (set by the CIE) */
193272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      Int     code_a_f;
193372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      Int     data_a_f;
193472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      Addr    initloc;
193572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      Int     ra_reg;
19365c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      /* The rest of these fields can be modifed by
19375c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         run_CF_instruction. */
19385c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      /* The LOC entry */
193972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      Addr    loc;
1940de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      /* We need a stack of these in order to handle
19413d026b18e0b41e5f13336f1997054f56cbd89da0sewardj         DW_CFA_{remember,restore}_state. */
1942de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      struct UnwindContextState {
1943de1b03da8168ecaa16d0fa05f83066f334c6948esewardj          /* The CFA entry.  This can be either reg+/-offset or an expr. */
1944de1b03da8168ecaa16d0fa05f83066f334c6948esewardj          Bool    cfa_is_regoff; /* True=>is reg+offset; False=>is expr */
1945de1b03da8168ecaa16d0fa05f83066f334c6948esewardj          Int     cfa_reg;
1946de1b03da8168ecaa16d0fa05f83066f334c6948esewardj          Int     cfa_off;  /* in bytes */
1947de1b03da8168ecaa16d0fa05f83066f334c6948esewardj          Int     cfa_expr_ix; /* index into cfa_exprs */
1948de1b03da8168ecaa16d0fa05f83066f334c6948esewardj          /* Register unwind rules.  */
1949de1b03da8168ecaa16d0fa05f83066f334c6948esewardj          RegRule reg[N_CFI_REGS];
1950de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      }
1951de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      state[N_RR_STACK];
1952de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      Int     state_sp; /* 0 <= state_sp < N_RR_STACK; points at the
1953de1b03da8168ecaa16d0fa05f83066f334c6948esewardj                           currently-in-use rule set. */
195472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      /* array of CfiExpr, shared by reg[] and cfa_expr_ix */
195572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      XArray* exprs;
19565c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   }
19575c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   UnwindContext;
19585c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
1959518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic void ppUnwindContext ( const UnwindContext* ctx )
196055022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj{
19613d026b18e0b41e5f13336f1997054f56cbd89da0sewardj   Int j, i;
196255022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj   VG_(printf)("0x%llx: ", (ULong)ctx->loc);
1963de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   for (j = 0; j <= ctx->state_sp; j++) {
1964518850bf0da07ed3e2244e307268ae0fd80e93a8florian      const struct UnwindContextState* ctxs = &ctx->state[j];
19653d026b18e0b41e5f13336f1997054f56cbd89da0sewardj      VG_(printf)("%s[%d]={ ", j > 0 ? " " : "", j);
1966de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      if (ctxs->cfa_is_regoff) {
1967de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         VG_(printf)("%d(r%d) ", ctxs->cfa_off, ctxs->cfa_reg);
1968de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      } else {
1969de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         vg_assert(ctx->exprs);
1970de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         VG_(printf)("{");
1971de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ML_(ppCfiExpr)( ctx->exprs, ctxs->cfa_expr_ix );
1972de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         VG_(printf)("} ");
1973de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      }
1974de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      VG_(printf)("{ ");
19753d026b18e0b41e5f13336f1997054f56cbd89da0sewardj      for (i = 0; i < N_CFI_REGS; i++)
1976de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ppRegRule(ctx->exprs, &ctxs->reg[i]);
19773d026b18e0b41e5f13336f1997054f56cbd89da0sewardj      VG_(printf)("}");
19783d026b18e0b41e5f13336f1997054f56cbd89da0sewardj   }
197955022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj   VG_(printf)("\n");
198055022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj}
198155022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
19825c638c2bda665e232ecf62b5443c93c3d6b7e06asewardjstatic void initUnwindContext ( /*OUT*/UnwindContext* ctx )
19835c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj{
19843d026b18e0b41e5f13336f1997054f56cbd89da0sewardj   Int j, i;
19853d026b18e0b41e5f13336f1997054f56cbd89da0sewardj   VG_(memset)(ctx, 0, sizeof(*ctx));
1986de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   /* ctx->code_a_f   = 0;
198772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   ctx->data_a_f      = 0;
1988de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   ctx->initloc       = 0; */
198972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   ctx->ra_reg        = RA_REG_DEFAULT;
1990de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   /* ctx->loc        = 0;
199172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   ctx->exprs         = NULL;
1992de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   ctx->state_sp        = 0; */
19933d026b18e0b41e5f13336f1997054f56cbd89da0sewardj   for (j = 0; j < N_RR_STACK; j++) {
1994de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      ctx->state[j].cfa_is_regoff = True;
1995de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      /* ctx->state[j].cfa_reg    = 0;
1996de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      ctx->state[j].cfa_off       = 0;
1997de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      ctx->state[j].cfa_expr_ix   = 0; */
19983d026b18e0b41e5f13336f1997054f56cbd89da0sewardj      for (i = 0; i < N_CFI_REGS; i++) {
1999de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         if (RR_Undef != 0)
2000de1b03da8168ecaa16d0fa05f83066f334c6948esewardj           ctx->state[j].reg[i].tag = RR_Undef;
2001de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         /* ctx->state[j].reg[i].arg = 0; */
20023d026b18e0b41e5f13336f1997054f56cbd89da0sewardj      }
2003d2aac89707eddf73bccf7c09a1472b3bb6a5ec32sewardj#     if defined(VGA_arm)
2004d2aac89707eddf73bccf7c09a1472b3bb6a5ec32sewardj      /* All callee-saved registers (or at least the ones we are
2005d2aac89707eddf73bccf7c09a1472b3bb6a5ec32sewardj         summarising for) should start out as RR_Same, on ARM. */
2006d2aac89707eddf73bccf7c09a1472b3bb6a5ec32sewardj      ctx->state[j].reg[11].tag = RR_Same;
2007d2aac89707eddf73bccf7c09a1472b3bb6a5ec32sewardj      /* ctx->state[j].reg[13].tag = RR_Same; */
2008d2aac89707eddf73bccf7c09a1472b3bb6a5ec32sewardj      ctx->state[j].reg[14].tag = RR_Same;
2009d2aac89707eddf73bccf7c09a1472b3bb6a5ec32sewardj      ctx->state[j].reg[12].tag = RR_Same;
2010fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj      ctx->state[j].reg[7].tag  = RR_Same;
2011d2aac89707eddf73bccf7c09a1472b3bb6a5ec32sewardj      /* this can't be right though: R12 (IP) isn't callee saved. */
2012821283b2110420321fd3f60afcc799b287788c68sewardj#     elif defined(VGA_arm64)
2013821283b2110420321fd3f60afcc799b287788c68sewardj      /* Callee-saved registers (that we are interested in) should
2014821283b2110420321fd3f60afcc799b287788c68sewardj         start out as RR_Same. */
2015821283b2110420321fd3f60afcc799b287788c68sewardj      ctx->state[j].reg[29/*FP*/].tag = RR_Same;
2016821283b2110420321fd3f60afcc799b287788c68sewardj      ctx->state[j].reg[30/*LR*/].tag = RR_Same;
2017d2aac89707eddf73bccf7c09a1472b3bb6a5ec32sewardj#     endif
20185c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   }
20195c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj}
20205c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
202135165537cfa2da18220e55e23f21228c1e2591fesewardj
2022c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj/* A structure which holds information needed by read_encoded_Addr().
20231936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj*/
20241936f8b3b201839583a39d0514049bcb1e3c3c2bsewardjtypedef
20251936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   struct {
20265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      UChar    encoding;
20275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiCursor ehframe_image;
20285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      Addr     ehframe_avma;
20295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      Addr     text_bias;
20308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      Addr     got_avma;
20311936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   }
20321936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj   AddressDecodingInfo;
20331936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj
20341936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj
20359ce110d9f1a1cb51d24abe9596feb4f8ccefa612njn/* ------------ Deal with summary-info records ------------ */
20369ce110d9f1a1cb51d24abe9596feb4f8ccefa612njn
203755022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj/* --------------- Summarisation --------------- */
203835165537cfa2da18220e55e23f21228c1e2591fesewardj
203972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Forward */
204072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjstatic
2041518850bf0da07ed3e2244e307268ae0fd80e93a8florianInt copy_convert_CfiExpr_tree ( XArray* dst, const UnwindContext* srcuc,
2042518850bf0da07ed3e2244e307268ae0fd80e93a8florian                                Int nd );
204372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
204435165537cfa2da18220e55e23f21228c1e2591fesewardj/* Summarise ctx into si, if possible.  Returns True if successful.
204535165537cfa2da18220e55e23f21228c1e2591fesewardj   This is taken to be just after ctx's loc advances; hence the
20468eb413204b3d80f52d207e8292c952f74faa2ca6sewardj   summary is up to but not including the current loc.  This works
20478eb413204b3d80f52d207e8292c952f74faa2ca6sewardj   on both x86 and amd64.
204835165537cfa2da18220e55e23f21228c1e2591fesewardj*/
20495c3dba227192de63d86f65ec7d9597c132818c37philippestatic Bool summarise_context(/*OUT*/Addr* base,
20505c3dba227192de63d86f65ec7d9597c132818c37philippe                              /*OUT*/UInt* len,
20515c3dba227192de63d86f65ec7d9597c132818c37philippe                              /*OUT*/DiCfSI_m* si_m,
20522fd38908d48d2a081e59ae67ffdb76b7f611ee8etom                               Addr loc_start,
2053518850bf0da07ed3e2244e307268ae0fd80e93a8florian	                       const UnwindContext* ctx,
2054518850bf0da07ed3e2244e307268ae0fd80e93a8florian                               DebugInfo* debuginfo )
205535165537cfa2da18220e55e23f21228c1e2591fesewardj{
20568eb413204b3d80f52d207e8292c952f74faa2ca6sewardj   Int why = 0;
2057518850bf0da07ed3e2244e307268ae0fd80e93a8florian   const struct UnwindContextState* ctxs;
20585c3dba227192de63d86f65ec7d9597c132818c37philippe
20595c3dba227192de63d86f65ec7d9597c132818c37philippe   *base = 0;
20605c3dba227192de63d86f65ec7d9597c132818c37philippe   *len = 0;
20615c3dba227192de63d86f65ec7d9597c132818c37philippe   VG_(bzero_inline)(si_m, sizeof(*si_m));
20625c3dba227192de63d86f65ec7d9597c132818c37philippe
206335165537cfa2da18220e55e23f21228c1e2591fesewardj
2064de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   /* Guard against obviously stupid settings of the reg-rule stack
2065de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      pointer. */
2066de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   if (ctx->state_sp < 0)           { why = 8; goto failed; }
2067de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   if (ctx->state_sp >= N_RR_STACK) { why = 9; goto failed; }
2068de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   ctxs = &ctx->state[ctx->state_sp];
2069de1b03da8168ecaa16d0fa05f83066f334c6948esewardj
20703026f71684a930286186aa10fef266c304672e8fsewardj   /* First, summarise the method for generating the CFA */
2071de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   if (!ctxs->cfa_is_regoff) {
20727888e2204fff6e7429236b4227ed16594e7743b9sewardj      /* it was set by DW_CFA_def_cfa_expression; try to convert */
20737888e2204fff6e7429236b4227ed16594e7743b9sewardj      XArray *src, *dst;
20747888e2204fff6e7429236b4227ed16594e7743b9sewardj      Int    conv;
20757888e2204fff6e7429236b4227ed16594e7743b9sewardj      src = ctx->exprs;
2076b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      dst = debuginfo->cfsi_exprs;
20777888e2204fff6e7429236b4227ed16594e7743b9sewardj      if (src && (VG_(sizeXA)(src) > 0) && (!dst)) {
20789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         dst = VG_(newXA)( ML_(dinfo_zalloc), "di.ccCt.1", ML_(dinfo_free),
20797888e2204fff6e7429236b4227ed16594e7743b9sewardj                           sizeof(CfiExpr) );
2080b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         debuginfo->cfsi_exprs = dst;
20817888e2204fff6e7429236b4227ed16594e7743b9sewardj      }
20827888e2204fff6e7429236b4227ed16594e7743b9sewardj      conv = copy_convert_CfiExpr_tree
2083de1b03da8168ecaa16d0fa05f83066f334c6948esewardj                    ( dst, ctx, ctxs->cfa_expr_ix );
20847888e2204fff6e7429236b4227ed16594e7743b9sewardj      vg_assert(conv >= -1);
20857888e2204fff6e7429236b4227ed16594e7743b9sewardj      if (conv == -1) { why = 6; goto failed; }
20865c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_how = CFIC_EXPR;
20875c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_off = conv;
2088b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (0 && debuginfo->ddump_frames)
20897888e2204fff6e7429236b4227ed16594e7743b9sewardj         ML_(ppCfiExpr)(dst, conv);
20903026f71684a930286186aa10fef266c304672e8fsewardj   }
20913026f71684a930286186aa10fef266c304672e8fsewardj   else
2092de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   if (ctxs->cfa_is_regoff && ctxs->cfa_reg == SP_REG) {
20935c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_off = ctxs->cfa_off;
20945db15403e889d4db339b342bc2a824ef0bfaa654sewardj#     if defined(VGA_x86) || defined(VGA_amd64) || defined(VGA_s390x) \
2095112711afefcfcd43680c7c4aa8d38ef180e8811esewardj         || defined(VGA_mips32) || defined(VGA_mips64) \
2096112711afefcfcd43680c7c4aa8d38ef180e8811esewardj         || defined(VGA_tilegx)
20975c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_how = CFIC_IA_SPREL;
20983026f71684a930286186aa10fef266c304672e8fsewardj#     elif defined(VGA_arm)
20995c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_how = CFIC_ARM_R13REL;
2100f0c1250e324f6684757c6a15545366447ef1d64fsewardj#     elif defined(VGA_arm64)
21015c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_how = CFIC_ARM64_SPREL;
21023026f71684a930286186aa10fef266c304672e8fsewardj#     else
21035c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_how = 0; /* invalid */
21043026f71684a930286186aa10fef266c304672e8fsewardj#     endif
21053026f71684a930286186aa10fef266c304672e8fsewardj   }
21063026f71684a930286186aa10fef266c304672e8fsewardj   else
2107de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   if (ctxs->cfa_is_regoff && ctxs->cfa_reg == FP_REG) {
21085c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_off = ctxs->cfa_off;
21095db15403e889d4db339b342bc2a824ef0bfaa654sewardj#     if defined(VGA_x86) || defined(VGA_amd64) || defined(VGA_s390x) \
2110112711afefcfcd43680c7c4aa8d38ef180e8811esewardj         || defined(VGA_mips32) || defined(VGA_mips64) \
2111112711afefcfcd43680c7c4aa8d38ef180e8811esewardj         || defined(VGA_tilegx)
21125c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_how = CFIC_IA_BPREL;
21133026f71684a930286186aa10fef266c304672e8fsewardj#     elif defined(VGA_arm)
21145c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_how = CFIC_ARM_R12REL;
2115821283b2110420321fd3f60afcc799b287788c68sewardj#     elif defined(VGA_arm64)
21165c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_how = CFIC_ARM64_X29REL;
21173026f71684a930286186aa10fef266c304672e8fsewardj#     else
21185c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_how = 0; /* invalid */
21193026f71684a930286186aa10fef266c304672e8fsewardj#     endif
21203026f71684a930286186aa10fef266c304672e8fsewardj   }
21213026f71684a930286186aa10fef266c304672e8fsewardj#  if defined(VGA_arm)
21223026f71684a930286186aa10fef266c304672e8fsewardj   else
21233026f71684a930286186aa10fef266c304672e8fsewardj   if (ctxs->cfa_is_regoff && ctxs->cfa_reg == 11/*??_REG*/) {
21245c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_how = CFIC_ARM_R11REL;
21255c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_off = ctxs->cfa_off;
21263026f71684a930286186aa10fef266c304672e8fsewardj   }
2127fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj   else
2128fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj   if (ctxs->cfa_is_regoff && ctxs->cfa_reg == 7/*??_REG*/) {
21295c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_how = CFIC_ARM_R7REL;
21305c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_off = ctxs->cfa_off;
2131fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj   }
2132f0c1250e324f6684757c6a15545366447ef1d64fsewardj#  elif defined(VGA_arm64)
2133821283b2110420321fd3f60afcc799b287788c68sewardj   // do we need any arm64 specifics here?
21343026f71684a930286186aa10fef266c304672e8fsewardj#  endif
21353026f71684a930286186aa10fef266c304672e8fsewardj   else {
21368eb413204b3d80f52d207e8292c952f74faa2ca6sewardj      why = 1;
213735165537cfa2da18220e55e23f21228c1e2591fesewardj      goto failed;
213835165537cfa2da18220e55e23f21228c1e2591fesewardj   }
213935165537cfa2da18220e55e23f21228c1e2591fesewardj
214072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj#  define SUMMARISE_HOW(_how, _off, _ctxreg)                  \
214172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   switch (_ctxreg.tag) {                                     \
214272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      case RR_Undef:                                          \
214372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         _how = CFIR_UNKNOWN;   _off = 0; break;              \
214472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      case RR_Same:                                           \
214572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         _how = CFIR_SAME;      _off = 0; break;              \
214672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      case RR_CFAOff:                                         \
214772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         _how = CFIR_MEMCFAREL; _off = _ctxreg.arg; break;    \
214872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      case RR_CFAValOff:                                      \
214972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         _how = CFIR_CFAREL;    _off = _ctxreg.arg; break;    \
215072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      case RR_ValExpr: {                                      \
215172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         XArray *src, *dst;                                   \
215272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         Int    conv;                                         \
215372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         src = ctx->exprs;                                    \
2154b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         dst = debuginfo->cfsi_exprs;                         \
215572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         if (src && (VG_(sizeXA)(src) > 0) && (!dst)) {       \
2156b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            dst = VG_(newXA)( ML_(dinfo_zalloc),              \
21579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                              "di.ccCt.2",                    \
2158b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                              ML_(dinfo_free),                \
215972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj                              sizeof(CfiExpr) );              \
2160b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            debuginfo->cfsi_exprs = dst;                      \
216172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         }                                                    \
216272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         conv = copy_convert_CfiExpr_tree                     \
216372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj                       ( dst, ctx, _ctxreg.arg );             \
216472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         vg_assert(conv >= -1);                               \
216572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         if (conv == -1) { why = 7; goto failed; }            \
216672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         _how = CFIR_EXPR;                                    \
216772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         _off = conv;                                         \
2168b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (0 && debuginfo->ddump_frames)                    \
216972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            ML_(ppCfiExpr)(dst, conv);                        \
217072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         break;                                               \
217172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      }                                                       \
217272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      default:                                                \
217372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         why = 2; goto failed; /* otherwise give up */        \
217435165537cfa2da18220e55e23f21228c1e2591fesewardj   }
217535165537cfa2da18220e55e23f21228c1e2591fesewardj
2176f0c1250e324f6684757c6a15545366447ef1d64fsewardj
21773026f71684a930286186aa10fef266c304672e8fsewardj#  if defined(VGA_x86) || defined(VGA_amd64)
21783026f71684a930286186aa10fef266c304672e8fsewardj
21793026f71684a930286186aa10fef266c304672e8fsewardj   /* --- entire tail of this fn specialised for x86/amd64 --- */
21803026f71684a930286186aa10fef266c304672e8fsewardj
21815c3dba227192de63d86f65ec7d9597c132818c37philippe   SUMMARISE_HOW(si_m->ra_how, si_m->ra_off,
21825c3dba227192de63d86f65ec7d9597c132818c37philippe                               ctxs->reg[ctx->ra_reg] );
21835c3dba227192de63d86f65ec7d9597c132818c37philippe   SUMMARISE_HOW(si_m->bp_how, si_m->bp_off,
21845c3dba227192de63d86f65ec7d9597c132818c37philippe                               ctxs->reg[FP_REG] );
218535165537cfa2da18220e55e23f21228c1e2591fesewardj
21868eb413204b3d80f52d207e8292c952f74faa2ca6sewardj   /* on x86/amd64, it seems the old %{e,r}sp value before the call is
21878eb413204b3d80f52d207e8292c952f74faa2ca6sewardj      always the same as the CFA.  Therefore ... */
21885c3dba227192de63d86f65ec7d9597c132818c37philippe   si_m->sp_how = CFIR_CFAREL;
21895c3dba227192de63d86f65ec7d9597c132818c37philippe   si_m->sp_off = 0;
219035165537cfa2da18220e55e23f21228c1e2591fesewardj
21918eb413204b3d80f52d207e8292c952f74faa2ca6sewardj   /* also, gcc says "Undef" for %{e,r}bp when it is unchanged.  So
21928eb413204b3d80f52d207e8292c952f74faa2ca6sewardj      .. */
2193de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   if (ctxs->reg[FP_REG].tag == RR_Undef)
21945c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->bp_how = CFIR_SAME;
219535165537cfa2da18220e55e23f21228c1e2591fesewardj
219635165537cfa2da18220e55e23f21228c1e2591fesewardj   /* knock out some obviously stupid cases */
21975c3dba227192de63d86f65ec7d9597c132818c37philippe   if (si_m->ra_how == CFIR_SAME)
21988eb413204b3d80f52d207e8292c952f74faa2ca6sewardj      { why = 3; goto failed; }
219935165537cfa2da18220e55e23f21228c1e2591fesewardj
220035165537cfa2da18220e55e23f21228c1e2591fesewardj   /* bogus looking range?  Note, we require that the difference is
220135165537cfa2da18220e55e23f21228c1e2591fesewardj      representable in 32 bits. */
22028eb413204b3d80f52d207e8292c952f74faa2ca6sewardj   if (loc_start >= ctx->loc)
22038eb413204b3d80f52d207e8292c952f74faa2ca6sewardj      { why = 4; goto failed; }
220435165537cfa2da18220e55e23f21228c1e2591fesewardj   if (ctx->loc - loc_start > 10000000 /* let's say */)
22058eb413204b3d80f52d207e8292c952f74faa2ca6sewardj      { why = 5; goto failed; }
220635165537cfa2da18220e55e23f21228c1e2591fesewardj
22075c3dba227192de63d86f65ec7d9597c132818c37philippe   *base = loc_start + ctx->initloc;
22085c3dba227192de63d86f65ec7d9597c132818c37philippe   *len  = (UInt)(ctx->loc - loc_start);
220935165537cfa2da18220e55e23f21228c1e2591fesewardj
221035165537cfa2da18220e55e23f21228c1e2591fesewardj   return True;
221135165537cfa2da18220e55e23f21228c1e2591fesewardj
22123026f71684a930286186aa10fef266c304672e8fsewardj#  elif defined(VGA_arm)
22133026f71684a930286186aa10fef266c304672e8fsewardj
22143026f71684a930286186aa10fef266c304672e8fsewardj   /* ---- entire tail of this fn specialised for arm ---- */
22153026f71684a930286186aa10fef266c304672e8fsewardj
22165c3dba227192de63d86f65ec7d9597c132818c37philippe   SUMMARISE_HOW(si_m->r14_how, si_m->r14_off,
22175c3dba227192de63d86f65ec7d9597c132818c37philippe                                ctxs->reg[14] );
22183026f71684a930286186aa10fef266c304672e8fsewardj
22195c3dba227192de63d86f65ec7d9597c132818c37philippe   //SUMMARISE_HOW(si_m->r13_how, si_m->r13_off,
22205c3dba227192de63d86f65ec7d9597c132818c37philippe   //                             ctxs->reg[13] );
22213026f71684a930286186aa10fef266c304672e8fsewardj
22225c3dba227192de63d86f65ec7d9597c132818c37philippe   SUMMARISE_HOW(si_m->r12_how, si_m->r12_off,
22235c3dba227192de63d86f65ec7d9597c132818c37philippe                                ctxs->reg[FP_REG] );
22243026f71684a930286186aa10fef266c304672e8fsewardj
22255c3dba227192de63d86f65ec7d9597c132818c37philippe   SUMMARISE_HOW(si_m->r11_how, si_m->r11_off,
22265c3dba227192de63d86f65ec7d9597c132818c37philippe                                ctxs->reg[11/*FP_REG*/] );
22273026f71684a930286186aa10fef266c304672e8fsewardj
22285c3dba227192de63d86f65ec7d9597c132818c37philippe   SUMMARISE_HOW(si_m->r7_how, si_m->r7_off,
22295c3dba227192de63d86f65ec7d9597c132818c37philippe                               ctxs->reg[7] );
2230fa5ce5616a17e79828fbc79f30b02b5085151e3csewardj
22313026f71684a930286186aa10fef266c304672e8fsewardj   if (ctxs->reg[14/*LR*/].tag == RR_Same
22323026f71684a930286186aa10fef266c304672e8fsewardj       && ctx->ra_reg == 14/*as we expect it always to be*/) {
22333026f71684a930286186aa10fef266c304672e8fsewardj      /* Generate a trivial CfiExpr, which merely says "r14".  First
22343026f71684a930286186aa10fef266c304672e8fsewardj         ensure this DebugInfo has a cfsi_expr array in which to park
22353026f71684a930286186aa10fef266c304672e8fsewardj         it. */
22363026f71684a930286186aa10fef266c304672e8fsewardj      if (!debuginfo->cfsi_exprs)
22373026f71684a930286186aa10fef266c304672e8fsewardj         debuginfo->cfsi_exprs = VG_(newXA)( ML_(dinfo_zalloc),
22383026f71684a930286186aa10fef266c304672e8fsewardj                                             "di.ccCt.2a",
22393026f71684a930286186aa10fef266c304672e8fsewardj                                             ML_(dinfo_free),
22403026f71684a930286186aa10fef266c304672e8fsewardj                                             sizeof(CfiExpr) );
22415c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->ra_off = ML_(CfiExpr_CfiReg)( debuginfo->cfsi_exprs,
22425c3dba227192de63d86f65ec7d9597c132818c37philippe                                         Creg_ARM_R14);
22435c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->ra_how = CFIR_EXPR;
22443026f71684a930286186aa10fef266c304672e8fsewardj   } else {
22453026f71684a930286186aa10fef266c304672e8fsewardj      /* Just summarise it in the normal way */
22465c3dba227192de63d86f65ec7d9597c132818c37philippe      SUMMARISE_HOW(si_m->ra_how, si_m->ra_off,
22475c3dba227192de63d86f65ec7d9597c132818c37philippe                                  ctxs->reg[ctx->ra_reg] );
22483026f71684a930286186aa10fef266c304672e8fsewardj   }
22493026f71684a930286186aa10fef266c304672e8fsewardj
22503026f71684a930286186aa10fef266c304672e8fsewardj   /* on arm, it seems the old r13 (SP) value before the call is
22513026f71684a930286186aa10fef266c304672e8fsewardj      always the same as the CFA.  Therefore ... */
22525c3dba227192de63d86f65ec7d9597c132818c37philippe   si_m->r13_how = CFIR_CFAREL;
22535c3dba227192de63d86f65ec7d9597c132818c37philippe   si_m->r13_off = 0;
22543026f71684a930286186aa10fef266c304672e8fsewardj
22553026f71684a930286186aa10fef266c304672e8fsewardj   /* bogus looking range?  Note, we require that the difference is
22563026f71684a930286186aa10fef266c304672e8fsewardj      representable in 32 bits. */
22573026f71684a930286186aa10fef266c304672e8fsewardj   if (loc_start >= ctx->loc)
22583026f71684a930286186aa10fef266c304672e8fsewardj      { why = 4; goto failed; }
22593026f71684a930286186aa10fef266c304672e8fsewardj   if (ctx->loc - loc_start > 10000000 /* let's say */)
22603026f71684a930286186aa10fef266c304672e8fsewardj      { why = 5; goto failed; }
22613026f71684a930286186aa10fef266c304672e8fsewardj
22625c3dba227192de63d86f65ec7d9597c132818c37philippe   *base = loc_start + ctx->initloc;
22635c3dba227192de63d86f65ec7d9597c132818c37philippe   *len  = (UInt)(ctx->loc - loc_start);
22643026f71684a930286186aa10fef266c304672e8fsewardj
22653026f71684a930286186aa10fef266c304672e8fsewardj   return True;
22663026f71684a930286186aa10fef266c304672e8fsewardj
2267821283b2110420321fd3f60afcc799b287788c68sewardj#  elif defined(VGA_arm64)
2268821283b2110420321fd3f60afcc799b287788c68sewardj
2269821283b2110420321fd3f60afcc799b287788c68sewardj   /* --- entire tail of this fn specialised for arm64 --- */
2270821283b2110420321fd3f60afcc799b287788c68sewardj
22715c3dba227192de63d86f65ec7d9597c132818c37philippe   SUMMARISE_HOW(si_m->x30_how, si_m->x30_off, ctxs->reg[30/*LR*/]);
22725c3dba227192de63d86f65ec7d9597c132818c37philippe   SUMMARISE_HOW(si_m->x29_how, si_m->x29_off, ctxs->reg[29/*FP*/]);
2273821283b2110420321fd3f60afcc799b287788c68sewardj
2274821283b2110420321fd3f60afcc799b287788c68sewardj   if (ctxs->reg[30/*LR*/].tag == RR_Same
2275821283b2110420321fd3f60afcc799b287788c68sewardj       && ctx->ra_reg == 30/*as we expect it always to be*/) {
2276821283b2110420321fd3f60afcc799b287788c68sewardj      /* Generate a trivial CfiExpr, which merely says "x30".  First
2277821283b2110420321fd3f60afcc799b287788c68sewardj         ensure this DebugInfo has a cfsi_expr array in which to park
2278821283b2110420321fd3f60afcc799b287788c68sewardj         it. */
2279821283b2110420321fd3f60afcc799b287788c68sewardj      if (!debuginfo->cfsi_exprs)
2280821283b2110420321fd3f60afcc799b287788c68sewardj         debuginfo->cfsi_exprs = VG_(newXA)( ML_(dinfo_zalloc),
2281821283b2110420321fd3f60afcc799b287788c68sewardj                                             "di.ccCt.2a-arm64",
2282821283b2110420321fd3f60afcc799b287788c68sewardj                                             ML_(dinfo_free),
2283821283b2110420321fd3f60afcc799b287788c68sewardj                                             sizeof(CfiExpr) );
22845c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->ra_off = ML_(CfiExpr_CfiReg)( debuginfo->cfsi_exprs,
22855c3dba227192de63d86f65ec7d9597c132818c37philippe                                          Creg_ARM64_X30);
22865c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->ra_how = CFIR_EXPR;
2287821283b2110420321fd3f60afcc799b287788c68sewardj   } else {
2288821283b2110420321fd3f60afcc799b287788c68sewardj      /* Just summarise it in the normal way */
22895c3dba227192de63d86f65ec7d9597c132818c37philippe      SUMMARISE_HOW(si_m->ra_how, si_m->ra_off, ctxs->reg[ctx->ra_reg]);
2290821283b2110420321fd3f60afcc799b287788c68sewardj   }
2291821283b2110420321fd3f60afcc799b287788c68sewardj
2292821283b2110420321fd3f60afcc799b287788c68sewardj   /* on arm64, it seems the old SP value before the call is always
2293821283b2110420321fd3f60afcc799b287788c68sewardj      the same as the CFA.  Therefore ... */
22945c3dba227192de63d86f65ec7d9597c132818c37philippe   si_m->sp_how = CFIR_CFAREL;
22955c3dba227192de63d86f65ec7d9597c132818c37philippe   si_m->sp_off = 0;
2296821283b2110420321fd3f60afcc799b287788c68sewardj
2297821283b2110420321fd3f60afcc799b287788c68sewardj   /* bogus looking range?  Note, we require that the difference is
2298821283b2110420321fd3f60afcc799b287788c68sewardj      representable in 32 bits. */
2299821283b2110420321fd3f60afcc799b287788c68sewardj   if (loc_start >= ctx->loc)
2300821283b2110420321fd3f60afcc799b287788c68sewardj      { why = 4; goto failed; }
2301821283b2110420321fd3f60afcc799b287788c68sewardj   if (ctx->loc - loc_start > 10000000 /* let's say */)
2302821283b2110420321fd3f60afcc799b287788c68sewardj      { why = 5; goto failed; }
2303821283b2110420321fd3f60afcc799b287788c68sewardj
23045c3dba227192de63d86f65ec7d9597c132818c37philippe   *base = loc_start + ctx->initloc;
23055c3dba227192de63d86f65ec7d9597c132818c37philippe   *len  = (UInt)(ctx->loc - loc_start);
2306821283b2110420321fd3f60afcc799b287788c68sewardj
2307821283b2110420321fd3f60afcc799b287788c68sewardj   return True;
2308821283b2110420321fd3f60afcc799b287788c68sewardj
2309b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#  elif defined(VGA_s390x)
2310b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
2311f0c1250e324f6684757c6a15545366447ef1d64fsewardj   /* --- entire tail of this fn specialised for s390 --- */
2312f0c1250e324f6684757c6a15545366447ef1d64fsewardj
23135c3dba227192de63d86f65ec7d9597c132818c37philippe   SUMMARISE_HOW(si_m->ra_how, si_m->ra_off,
23145c3dba227192de63d86f65ec7d9597c132818c37philippe                               ctxs->reg[ctx->ra_reg] );
23155c3dba227192de63d86f65ec7d9597c132818c37philippe   SUMMARISE_HOW(si_m->fp_how, si_m->fp_off,
23165c3dba227192de63d86f65ec7d9597c132818c37philippe                               ctxs->reg[FP_REG] );
23175c3dba227192de63d86f65ec7d9597c132818c37philippe   SUMMARISE_HOW(si_m->sp_how, si_m->sp_off,
23185c3dba227192de63d86f65ec7d9597c132818c37philippe                               ctxs->reg[SP_REG] );
2319b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
2320b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   /* change some defaults to consumable values */
23215c3dba227192de63d86f65ec7d9597c132818c37philippe   if (si_m->sp_how == CFIR_UNKNOWN)
23225c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->sp_how = CFIR_SAME;
2323b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
23245c3dba227192de63d86f65ec7d9597c132818c37philippe   if (si_m->fp_how == CFIR_UNKNOWN)
23255c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->fp_how = CFIR_SAME;
2326b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
23275c3dba227192de63d86f65ec7d9597c132818c37philippe   if (si_m->cfa_how == CFIR_UNKNOWN) {
23285c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_how = CFIC_IA_SPREL;
23295c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_off = 160;
2330b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   }
23315c3dba227192de63d86f65ec7d9597c132818c37philippe   if (si_m->ra_how == CFIR_UNKNOWN) {
2332b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      if (!debuginfo->cfsi_exprs)
2333b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         debuginfo->cfsi_exprs = VG_(newXA)( ML_(dinfo_zalloc),
2334b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                                             "di.ccCt.2a",
2335b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                                             ML_(dinfo_free),
2336b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj                                             sizeof(CfiExpr) );
23375c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->ra_how = CFIR_EXPR;
23385c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->ra_off = ML_(CfiExpr_CfiReg)( debuginfo->cfsi_exprs,
2339b6ba6d288e6000a8f95fba1dea671e0b53e26043florian                                          Creg_S390_LR);
2340b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   }
2341b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
2342b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   /* knock out some obviously stupid cases */
23435c3dba227192de63d86f65ec7d9597c132818c37philippe   if (si_m->ra_how == CFIR_SAME)
2344b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      { why = 3; goto failed; }
2345b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
2346b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   /* bogus looking range?  Note, we require that the difference is
2347b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      representable in 32 bits. */
2348b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   if (loc_start >= ctx->loc)
2349b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      { why = 4; goto failed; }
2350b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   if (ctx->loc - loc_start > 10000000 /* let's say */)
2351b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj      { why = 5; goto failed; }
2352b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
23535c3dba227192de63d86f65ec7d9597c132818c37philippe   *base = loc_start + ctx->initloc;
23545c3dba227192de63d86f65ec7d9597c132818c37philippe   *len  = (UInt)(ctx->loc - loc_start);
2355b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
2356b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj   return True;
2357b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
23584df0bfc0614379192c780c944415dc420d9cfe8epetarj#  elif defined(VGA_mips32) || defined(VGA_mips64)
2359112711afefcfcd43680c7c4aa8d38ef180e8811esewardj
23605db15403e889d4db339b342bc2a824ef0bfaa654sewardj   /* --- entire tail of this fn specialised for mips --- */
2361112711afefcfcd43680c7c4aa8d38ef180e8811esewardj
23625c3dba227192de63d86f65ec7d9597c132818c37philippe   SUMMARISE_HOW(si_m->ra_how, si_m->ra_off,
23635c3dba227192de63d86f65ec7d9597c132818c37philippe                               ctxs->reg[ctx->ra_reg] );
23645c3dba227192de63d86f65ec7d9597c132818c37philippe   SUMMARISE_HOW(si_m->fp_how, si_m->fp_off,
23655c3dba227192de63d86f65ec7d9597c132818c37philippe                               ctxs->reg[FP_REG] );
23665c3dba227192de63d86f65ec7d9597c132818c37philippe   SUMMARISE_HOW(si_m->sp_how, si_m->sp_off,
23675c3dba227192de63d86f65ec7d9597c132818c37philippe                               ctxs->reg[SP_REG] );
23685c3dba227192de63d86f65ec7d9597c132818c37philippe   si_m->sp_how = CFIR_CFAREL;
23695c3dba227192de63d86f65ec7d9597c132818c37philippe   si_m->sp_off = 0;
23705c3dba227192de63d86f65ec7d9597c132818c37philippe
23715c3dba227192de63d86f65ec7d9597c132818c37philippe   if (si_m->fp_how == CFIR_UNKNOWN)
23725c3dba227192de63d86f65ec7d9597c132818c37philippe       si_m->fp_how = CFIR_SAME;
23735c3dba227192de63d86f65ec7d9597c132818c37philippe   if (si_m->cfa_how == CFIR_UNKNOWN) {
23745c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_how = CFIC_IA_SPREL;
23755c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->cfa_off = 160;
23765db15403e889d4db339b342bc2a824ef0bfaa654sewardj   }
23775c3dba227192de63d86f65ec7d9597c132818c37philippe   if (si_m->ra_how == CFIR_UNKNOWN) {
23785db15403e889d4db339b342bc2a824ef0bfaa654sewardj      if (!debuginfo->cfsi_exprs)
23795db15403e889d4db339b342bc2a824ef0bfaa654sewardj         debuginfo->cfsi_exprs = VG_(newXA)( ML_(dinfo_zalloc),
23805db15403e889d4db339b342bc2a824ef0bfaa654sewardj                                             "di.ccCt.2a",
23815db15403e889d4db339b342bc2a824ef0bfaa654sewardj                                             ML_(dinfo_free),
23825db15403e889d4db339b342bc2a824ef0bfaa654sewardj                                             sizeof(CfiExpr) );
23835c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->ra_how = CFIR_EXPR;
23845c3dba227192de63d86f65ec7d9597c132818c37philippe      si_m->ra_off = ML_(CfiExpr_CfiReg)( debuginfo->cfsi_exprs,
23855c3dba227192de63d86f65ec7d9597c132818c37philippe                                          Creg_MIPS_RA);
23865db15403e889d4db339b342bc2a824ef0bfaa654sewardj   }
23875db15403e889d4db339b342bc2a824ef0bfaa654sewardj
23885c3dba227192de63d86f65ec7d9597c132818c37philippe   if (si_m->ra_how == CFIR_SAME)
23895db15403e889d4db339b342bc2a824ef0bfaa654sewardj      { why = 3; goto failed; }
23905db15403e889d4db339b342bc2a824ef0bfaa654sewardj
23915db15403e889d4db339b342bc2a824ef0bfaa654sewardj   if (loc_start >= ctx->loc)
23925db15403e889d4db339b342bc2a824ef0bfaa654sewardj      { why = 4; goto failed; }
23935db15403e889d4db339b342bc2a824ef0bfaa654sewardj   if (ctx->loc - loc_start > 10000000 /* let's say */)
23945db15403e889d4db339b342bc2a824ef0bfaa654sewardj      { why = 5; goto failed; }
23955db15403e889d4db339b342bc2a824ef0bfaa654sewardj
23965c3dba227192de63d86f65ec7d9597c132818c37philippe   *base = loc_start + ctx->initloc;
23975c3dba227192de63d86f65ec7d9597c132818c37philippe   *len  = (UInt)(ctx->loc - loc_start);
23985db15403e889d4db339b342bc2a824ef0bfaa654sewardj
23995db15403e889d4db339b342bc2a824ef0bfaa654sewardj   return True;
2400112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#  elif defined(VGA_tilegx)
2401112711afefcfcd43680c7c4aa8d38ef180e8811esewardj
2402112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   /* --- entire tail of this fn specialised for tilegx --- */
2403112711afefcfcd43680c7c4aa8d38ef180e8811esewardj
2404112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   SUMMARISE_HOW(si_m->ra_how, si_m->ra_off,
2405112711afefcfcd43680c7c4aa8d38ef180e8811esewardj                               ctxs->reg[ctx->ra_reg] );
2406112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   SUMMARISE_HOW(si_m->fp_how, si_m->fp_off,
2407112711afefcfcd43680c7c4aa8d38ef180e8811esewardj                               ctxs->reg[FP_REG] );
2408112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   SUMMARISE_HOW(si_m->sp_how, si_m->sp_off,
2409112711afefcfcd43680c7c4aa8d38ef180e8811esewardj                               ctxs->reg[SP_REG] );
2410112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   si_m->sp_how = CFIR_CFAREL;
2411112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   si_m->sp_off = 0;
2412112711afefcfcd43680c7c4aa8d38ef180e8811esewardj
2413112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   if (si_m->fp_how == CFIR_UNKNOWN)
2414112711afefcfcd43680c7c4aa8d38ef180e8811esewardj       si_m->fp_how = CFIR_SAME;
2415112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   if (si_m->cfa_how == CFIR_UNKNOWN) {
2416112711afefcfcd43680c7c4aa8d38ef180e8811esewardj      si_m->cfa_how = CFIC_IA_SPREL;
2417112711afefcfcd43680c7c4aa8d38ef180e8811esewardj      si_m->cfa_off = 160;
2418112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   }
2419112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   if (si_m->ra_how == CFIR_UNKNOWN) {
2420112711afefcfcd43680c7c4aa8d38ef180e8811esewardj      if (!debuginfo->cfsi_exprs)
2421112711afefcfcd43680c7c4aa8d38ef180e8811esewardj         debuginfo->cfsi_exprs = VG_(newXA)( ML_(dinfo_zalloc),
2422112711afefcfcd43680c7c4aa8d38ef180e8811esewardj                                             "di.ccCt.2a",
2423112711afefcfcd43680c7c4aa8d38ef180e8811esewardj                                             ML_(dinfo_free),
2424112711afefcfcd43680c7c4aa8d38ef180e8811esewardj                                             sizeof(CfiExpr) );
2425112711afefcfcd43680c7c4aa8d38ef180e8811esewardj      si_m->ra_how = CFIR_EXPR;
2426112711afefcfcd43680c7c4aa8d38ef180e8811esewardj      si_m->ra_off = ML_(CfiExpr_CfiReg)( debuginfo->cfsi_exprs,
2427112711afefcfcd43680c7c4aa8d38ef180e8811esewardj                                          Creg_TILEGX_LR);
2428112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   }
2429112711afefcfcd43680c7c4aa8d38ef180e8811esewardj
2430112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   if (si_m->ra_how == CFIR_SAME)
2431112711afefcfcd43680c7c4aa8d38ef180e8811esewardj      { why = 3; goto failed; }
2432112711afefcfcd43680c7c4aa8d38ef180e8811esewardj
2433112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   if (loc_start >= ctx->loc)
2434112711afefcfcd43680c7c4aa8d38ef180e8811esewardj      { why = 4; goto failed; }
2435112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   if (ctx->loc - loc_start > 10000000 /* let's say */)
2436112711afefcfcd43680c7c4aa8d38ef180e8811esewardj      { why = 5; goto failed; }
24375db15403e889d4db339b342bc2a824ef0bfaa654sewardj
2438112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   *base = loc_start + ctx->initloc;
2439112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   *len  = (UInt)(ctx->loc - loc_start);
2440112711afefcfcd43680c7c4aa8d38ef180e8811esewardj
2441112711afefcfcd43680c7c4aa8d38ef180e8811esewardj   return True;
2442cae0cc22b83ffb260ee8379e92099c5a701944cbcarll#  elif defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
2443f0c1250e324f6684757c6a15545366447ef1d64fsewardj   /* These don't use CFI based unwinding (is that really true?) */
2444f0c1250e324f6684757c6a15545366447ef1d64fsewardj
24453026f71684a930286186aa10fef266c304672e8fsewardj#  else
24463026f71684a930286186aa10fef266c304672e8fsewardj#    error "Unknown arch"
24473026f71684a930286186aa10fef266c304672e8fsewardj#  endif
24483026f71684a930286186aa10fef266c304672e8fsewardj
2449821283b2110420321fd3f60afcc799b287788c68sewardj   /* --- non-specialised code after this point --- */
2450821283b2110420321fd3f60afcc799b287788c68sewardj
24513026f71684a930286186aa10fef266c304672e8fsewardj#  undef SUMMARISE_HOW
24523026f71684a930286186aa10fef266c304672e8fsewardj
245335165537cfa2da18220e55e23f21228c1e2591fesewardj  failed:
2454b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (VG_(clo_verbosity) > 2 || debuginfo->trace_cfi) {
245555022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj      VG_(message)(Vg_DebugMsg,
2456a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart                  "summarise_context(loc_start = %#lx)"
2457738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                  ": cannot summarise(why=%d):   \n", loc_start, why);
245855022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj      ppUnwindContext(ctx);
245955022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj   }
246035165537cfa2da18220e55e23f21228c1e2591fesewardj   return False;
246135165537cfa2da18220e55e23f21228c1e2591fesewardj}
246235165537cfa2da18220e55e23f21228c1e2591fesewardj
246372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Copy the tree rooted at srcuc->exprs node srcix to dstxa, on the
246472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   way converting any DwReg regs (regs numbered using the Dwarf scheme
246572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   defined by each architecture's ABI) into CfiRegs, which are
246672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   platform independent.  If the conversion isn't possible because
246772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   there is no equivalent register, return -1.  This has the
246872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   undesirable side effect of de-dagifying the input; oh well. */
246972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardjstatic Int copy_convert_CfiExpr_tree ( XArray*        dstxa,
2470518850bf0da07ed3e2244e307268ae0fd80e93a8florian                                       const UnwindContext* srcuc,
247172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj                                       Int            srcix )
247272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{
247372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   CfiExpr* src;
2474d2be8cc17fed04cbd701e9a2cc1cf365ff45cc44sewardj   Int      cpL, cpR, cpA;
247572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   XArray*  srcxa = srcuc->exprs;
247672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   vg_assert(srcxa);
247772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   vg_assert(dstxa);
247872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   vg_assert(srcix >= 0 && srcix < VG_(sizeXA)(srcxa));
247972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
248072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   src = VG_(indexXA)( srcxa, srcix );
248172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   switch (src->tag) {
248272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      case Cex_Undef:
248372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         return ML_(CfiExpr_Undef)( dstxa );
248472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      case Cex_Deref:
2485bd7aca648dd9ee152dbdc4474b533a55e543514csewardj         cpA = copy_convert_CfiExpr_tree( dstxa, srcuc, src->Cex.Deref.ixAddr );
2486bd7aca648dd9ee152dbdc4474b533a55e543514csewardj         if (cpA == -1)
2487bd7aca648dd9ee152dbdc4474b533a55e543514csewardj            return -1; /* propagate failure */
2488bd7aca648dd9ee152dbdc4474b533a55e543514csewardj         return ML_(CfiExpr_Deref)( dstxa, cpA );
248972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      case Cex_Const:
249072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         return ML_(CfiExpr_Const)( dstxa, src->Cex.Const.con );
249172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      case Cex_Binop:
249272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         cpL = copy_convert_CfiExpr_tree( dstxa, srcuc, src->Cex.Binop.ixL );
249372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         cpR = copy_convert_CfiExpr_tree( dstxa, srcuc, src->Cex.Binop.ixR );
249472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         vg_assert(cpL >= -1 && cpR >= -1);
249572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         if (cpL == -1 || cpR == -1)
249672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            return -1; /* propagate failure */
249772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         return ML_(CfiExpr_Binop)( dstxa, src->Cex.Binop.op, cpL, cpR );
249872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      case Cex_CfiReg:
249972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         /* should not see these in input (are created only by this
250072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            conversion step!) */
250172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         VG_(core_panic)("copy_convert_CfiExpr_tree: CfiReg in input");
2502d2be8cc17fed04cbd701e9a2cc1cf365ff45cc44sewardj      case Cex_DwReg: {
250372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         /* This is the only place where the conversion can fail. */
2504d2be8cc17fed04cbd701e9a2cc1cf365ff45cc44sewardj         Int dwreg __attribute__((unused));
250572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         dwreg = src->Cex.DwReg.reg;
25063026f71684a930286186aa10fef266c304672e8fsewardj#        if defined(VGA_x86) || defined(VGA_amd64)
250772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         if (dwreg == SP_REG)
25089365e3f48bc3efe2486bf4bc04111a2d89db5520sewardj            return ML_(CfiExpr_CfiReg)( dstxa, Creg_IA_SP );
250972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         if (dwreg == FP_REG)
25109365e3f48bc3efe2486bf4bc04111a2d89db5520sewardj            return ML_(CfiExpr_CfiReg)( dstxa, Creg_IA_BP );
251172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         if (dwreg == srcuc->ra_reg)
25129365e3f48bc3efe2486bf4bc04111a2d89db5520sewardj            return ML_(CfiExpr_CfiReg)( dstxa, Creg_IA_IP ); /* correct? */
25133026f71684a930286186aa10fef266c304672e8fsewardj#        elif defined(VGA_arm)
25143026f71684a930286186aa10fef266c304672e8fsewardj         if (dwreg == SP_REG)
25153026f71684a930286186aa10fef266c304672e8fsewardj            return ML_(CfiExpr_CfiReg)( dstxa, Creg_ARM_R13 );
25163026f71684a930286186aa10fef266c304672e8fsewardj         if (dwreg == FP_REG)
25173026f71684a930286186aa10fef266c304672e8fsewardj            return ML_(CfiExpr_CfiReg)( dstxa, Creg_ARM_R12 );
25183026f71684a930286186aa10fef266c304672e8fsewardj         if (dwreg == srcuc->ra_reg)
25193026f71684a930286186aa10fef266c304672e8fsewardj           return ML_(CfiExpr_CfiReg)( dstxa, Creg_ARM_R15 ); /* correct? */
2520b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj#        elif defined(VGA_s390x)
2521b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         if (dwreg == SP_REG)
2522b6ba6d288e6000a8f95fba1dea671e0b53e26043florian            return ML_(CfiExpr_CfiReg)( dstxa, Creg_S390_SP );
2523b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         if (dwreg == FP_REG)
2524b6ba6d288e6000a8f95fba1dea671e0b53e26043florian            return ML_(CfiExpr_CfiReg)( dstxa, Creg_S390_FP );
2525b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj         if (dwreg == srcuc->ra_reg)
2526b6ba6d288e6000a8f95fba1dea671e0b53e26043florian            return ML_(CfiExpr_CfiReg)( dstxa, Creg_S390_IA );
25274df0bfc0614379192c780c944415dc420d9cfe8epetarj#        elif defined(VGA_mips32) || defined(VGA_mips64)
25285db15403e889d4db339b342bc2a824ef0bfaa654sewardj         if (dwreg == SP_REG)
25295db15403e889d4db339b342bc2a824ef0bfaa654sewardj            return ML_(CfiExpr_CfiReg)( dstxa, Creg_IA_SP );
25305db15403e889d4db339b342bc2a824ef0bfaa654sewardj         if (dwreg == FP_REG)
25315db15403e889d4db339b342bc2a824ef0bfaa654sewardj            return ML_(CfiExpr_CfiReg)( dstxa, Creg_IA_BP );
25325db15403e889d4db339b342bc2a824ef0bfaa654sewardj         if (dwreg == srcuc->ra_reg)
25335db15403e889d4db339b342bc2a824ef0bfaa654sewardj            return ML_(CfiExpr_CfiReg)( dstxa, Creg_IA_IP );
2534f0c1250e324f6684757c6a15545366447ef1d64fsewardj#        elif defined(VGA_arm64)
2535f0c1250e324f6684757c6a15545366447ef1d64fsewardj         I_die_here;
2536cae0cc22b83ffb260ee8379e92099c5a701944cbcarll#        elif defined(VGA_ppc32) || defined(VGA_ppc64be) \
2537cae0cc22b83ffb260ee8379e92099c5a701944cbcarll            || defined(VGA_ppc64le)
2538112711afefcfcd43680c7c4aa8d38ef180e8811esewardj#        elif defined(VGA_tilegx)
2539112711afefcfcd43680c7c4aa8d38ef180e8811esewardj         if (dwreg == SP_REG)
2540112711afefcfcd43680c7c4aa8d38ef180e8811esewardj            return ML_(CfiExpr_CfiReg)( dstxa, Creg_TILEGX_SP );
2541112711afefcfcd43680c7c4aa8d38ef180e8811esewardj         if (dwreg == FP_REG)
2542112711afefcfcd43680c7c4aa8d38ef180e8811esewardj            return ML_(CfiExpr_CfiReg)( dstxa, Creg_TILEGX_BP );
2543112711afefcfcd43680c7c4aa8d38ef180e8811esewardj         if (dwreg == srcuc->ra_reg)
2544112711afefcfcd43680c7c4aa8d38ef180e8811esewardj            return ML_(CfiExpr_CfiReg)( dstxa, Creg_TILEGX_IP );
25453026f71684a930286186aa10fef266c304672e8fsewardj#        else
25463026f71684a930286186aa10fef266c304672e8fsewardj#           error "Unknown arch"
25473026f71684a930286186aa10fef266c304672e8fsewardj#        endif
254872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         /* else we must fail - can't represent the reg */
254972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         return -1;
2550d2be8cc17fed04cbd701e9a2cc1cf365ff45cc44sewardj      }
255172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      default:
255272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         VG_(core_panic)("copy_convert_CfiExpr_tree: default");
255372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   }
255472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj}
255572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
255672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
2557518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic void ppUnwindContext_summary ( const UnwindContext* ctx )
255835165537cfa2da18220e55e23f21228c1e2591fesewardj{
2559518850bf0da07ed3e2244e307268ae0fd80e93a8florian   const struct UnwindContextState* ctxs = &ctx->state[ctx->state_sp];
2560de1b03da8168ecaa16d0fa05f83066f334c6948esewardj
256135165537cfa2da18220e55e23f21228c1e2591fesewardj   VG_(printf)("0x%llx-1: ", (ULong)ctx->loc);
256235165537cfa2da18220e55e23f21228c1e2591fesewardj
2563de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   if (ctxs->cfa_reg == SP_REG) {
2564de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      VG_(printf)("SP/CFA=%d+SP   ", ctxs->cfa_off);
256535165537cfa2da18220e55e23f21228c1e2591fesewardj   } else
2566de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   if (ctxs->cfa_reg == FP_REG) {
2567de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      VG_(printf)("SP/CFA=%d+FP   ", ctxs->cfa_off);
256835165537cfa2da18220e55e23f21228c1e2591fesewardj   } else {
2569a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart      VG_(printf)("SP/CFA=unknown  ");
25705c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   }
257135165537cfa2da18220e55e23f21228c1e2591fesewardj
257235165537cfa2da18220e55e23f21228c1e2591fesewardj   VG_(printf)("RA=");
2573de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   ppRegRule( ctx->exprs, &ctxs->reg[ctx->ra_reg] );
257435165537cfa2da18220e55e23f21228c1e2591fesewardj
257535165537cfa2da18220e55e23f21228c1e2591fesewardj   VG_(printf)("FP=");
2576de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   ppRegRule( ctx->exprs, &ctxs->reg[FP_REG] );
25775c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   VG_(printf)("\n");
25785c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj}
25795c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
258055022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
258155022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj/* ------------ Pick apart DWARF2 byte streams ------------ */
258255022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
25835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic ULong step_le_u_encoded_literal ( DiCursor* data, UInt size )
2584ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj{
2585ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj   switch (size) {
25865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      case 8:  return (ULong)ML_(cur_step_ULong)( data );
25875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      case 4:  return (ULong)ML_(cur_step_UInt)( data );
25885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      case 2:  return (ULong)ML_(cur_step_UShort)( data );
25895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      case 1:  return (ULong)ML_(cur_step_UChar)( data );
2590ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj      default: vg_assert(0); /*NOTREACHED*/ return 0;
2591ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj   }
2592ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj}
2593ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj
25945d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic Long step_le_s_encoded_literal ( DiCursor* data, UInt size )
259572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{
259645ee036d5512d088f138c143e8be8c1002e452e4florian   ULong u64 = step_le_u_encoded_literal( data, size );
259745ee036d5512d088f138c143e8be8c1002e452e4florian   Long s64;
259872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   switch (size) {
2599237fd431ca0261d28ee5dec6d005af237002d0e0florian      case 8:  s64 = u64; break;
260045ee036d5512d088f138c143e8be8c1002e452e4florian      case 4:  s64 = u64 << 32; s64 >>= 32; break;
260145ee036d5512d088f138c143e8be8c1002e452e4florian      case 2:  s64 = u64 << 48; s64 >>= 48; break;
260245ee036d5512d088f138c143e8be8c1002e452e4florian      case 1:  s64 = u64 << 56; s64 >>= 56; break;
260372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      default: vg_assert(0); /*NOTREACHED*/ return 0;
260472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   }
260572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   return s64;
260672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj}
2607ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj
2608151a639d523a1d9b4cbd6629992e48ed8ee9408etomstatic UChar default_Addr_encoding ( void )
26092fd38908d48d2a081e59ae67ffdb76b7f611ee8etom{
26102fd38908d48d2a081e59ae67ffdb76b7f611ee8etom   switch (sizeof(Addr)) {
26112fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case 4: return DW_EH_PE_udata4;
26122fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case 8: return DW_EH_PE_udata8;
26132fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      default: vg_assert(0);
26142fd38908d48d2a081e59ae67ffdb76b7f611ee8etom   }
26152fd38908d48d2a081e59ae67ffdb76b7f611ee8etom}
26162fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
26178eb413204b3d80f52d207e8292c952f74faa2ca6sewardjstatic UInt size_of_encoded_Addr ( UChar encoding )
26182fd38908d48d2a081e59ae67ffdb76b7f611ee8etom{
26192fd38908d48d2a081e59ae67ffdb76b7f611ee8etom   if (encoding == DW_EH_PE_omit)
26202fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      return 0;
26212fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
26222fd38908d48d2a081e59ae67ffdb76b7f611ee8etom   switch (encoding & 0x07) {
26232fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_EH_PE_absptr: return sizeof(Addr);
26242fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_EH_PE_udata2: return sizeof(UShort);
26252fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_EH_PE_udata4: return sizeof(UInt);
26262fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_EH_PE_udata8: return sizeof(ULong);
26272fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      default: vg_assert(0);
26282fd38908d48d2a081e59ae67ffdb76b7f611ee8etom   }
26292fd38908d48d2a081e59ae67ffdb76b7f611ee8etom}
26302fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
2631518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic Addr step_encoded_Addr ( const AddressDecodingInfo* adi,
26325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                /*MOD*/DiCursor* data )
26332fd38908d48d2a081e59ae67ffdb76b7f611ee8etom{
2634ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj   /* Regarding the handling of DW_EH_PE_absptr.  DWARF3 says this
2635ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj      denotes an absolute address, hence you would think 'base' is
2636ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj      zero.  However, that is nonsensical (unless relocations are to
2637ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj      be applied to the unwind data before reading it, which sounds
2638ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj      unlikely).  My interpretation is that DW_EH_PE_absptr indicates
2639ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj      an address relative to where the object was loaded (technically,
2640ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj      relative to its stated load VMA, hence the use of text_bias
2641ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj      rather than text_avma).  Hmm, should we use text_bias or
2642ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj      text_avma here?  Not sure.
2643ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj
2644ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj      This view appears to be supported by DWARF3 spec sec 7.3
2645ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj      "Executable Objects and Shared Objects":
2646ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj
2647ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj         This requirement makes the debugging information for shared
2648ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj         objects position independent.  Virtual addresses in a shared
2649ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj         object may be calculated by adding the offset to the base
2650ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj         address at which the object was attached.  This offset is
2651ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj         available in the run-time linker's data structures.
2652ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj   */
26535d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   Addr     base;
26545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   Word     offset;
26555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UChar    encoding      = adi->encoding;
26565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiCursor ehframe_image = adi->ehframe_image;
26575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   Addr     ehframe_avma  = adi->ehframe_avma;
26588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj   Addr     got_avma      = adi->got_avma;
26592fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
26602fd38908d48d2a081e59ae67ffdb76b7f611ee8etom   vg_assert((encoding & DW_EH_PE_indirect) == 0);
26612fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
26622fd38908d48d2a081e59ae67ffdb76b7f611ee8etom   switch (encoding & 0x70) {
26632fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_EH_PE_absptr:
2664ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj         base = adi->text_bias;
26652fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         break;
26662fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_EH_PE_pcrel:
26675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         base = ehframe_avma + ML_(cur_minus)(*data, ehframe_image);
26682fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         break;
26692fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_EH_PE_datarel:
26708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj         base = got_avma;
26712fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         break;
26722fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_EH_PE_textrel:
26732fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         vg_assert(0);
26742fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         base = /* text base address */ 0;
26752fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         break;
26762fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_EH_PE_funcrel:
26772fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         base = 0;
26782fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         break;
26792fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_EH_PE_aligned:
26802fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         base = 0;
26815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         offset = ML_(cur_minus)(*data, ehframe_image);
26822fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         if ((offset % sizeof(Addr)) != 0) {
26835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            Word nbytes = sizeof(Addr) - (offset % sizeof(Addr));
26845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            *data = ML_(cur_plus)(*data, nbytes);
26852fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         }
26862fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         break;
26872fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      default:
26882fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         vg_assert(0);
26892fd38908d48d2a081e59ae67ffdb76b7f611ee8etom   }
26902fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
2691325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj   if ((encoding & 0x07) == 0x00)
26928eb413204b3d80f52d207e8292c952f74faa2ca6sewardj      encoding |= default_Addr_encoding();
26932fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
26942fd38908d48d2a081e59ae67ffdb76b7f611ee8etom   switch (encoding & 0x0f) {
26952fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_EH_PE_udata2:
26965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         return base + ML_(cur_step_UShort)(data);
26972fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_EH_PE_udata4:
26985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         return base + ML_(cur_step_UInt)(data);
26992fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_EH_PE_udata8:
27005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         return base + ML_(cur_step_ULong)(data);
27012fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_EH_PE_sdata2:
27025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         return base + ML_(cur_step_Short)(data);
27032fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_EH_PE_sdata4:
27045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         return base + ML_(cur_step_Int)(data);
27052fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_EH_PE_sdata8:
27065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         return base + ML_(cur_step_Long)(data);
27072fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      default:
2708325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj         vg_assert2(0, "read encoded address %d\n", encoding & 0x0f);
27092fd38908d48d2a081e59ae67ffdb76b7f611ee8etom   }
27102fd38908d48d2a081e59ae67ffdb76b7f611ee8etom}
27112fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
27125c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
271372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* ------------ Run/show DWARF3 expressions ---------- */
271472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
271572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj/* Convert the DWARF3 expression in expr[0 .. exprlen-1] into a dag
271672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   (of CfiExprs) stored in ctx->exprs, and return the index in
271772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   ctx->exprs of the root node.  Or fail in which case return -1. */
27187888e2204fff6e7429236b4227ed16594e7743b9sewardj/* IMPORTANT: when adding expression forms here, also remember to
27197888e2204fff6e7429236b4227ed16594e7743b9sewardj   add suitable evaluation code in evalCfiExpr in debuginfo.c. */
2720518850bf0da07ed3e2244e307268ae0fd80e93a8florianstatic Int dwarfexpr_to_dag ( const UnwindContext* ctx,
27215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                              DiCursor expr, Int exprlen,
272272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj                              Bool push_cfa_at_start,
272372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj                              Bool ddump_frames )
272472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj{
272572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj#  define N_EXPR_STACK 20
272672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
272772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj#  define PUSH(_arg)                               \
272872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      do {                                         \
272972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         vg_assert(sp >= -1 && sp < N_EXPR_STACK); \
273072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         if (sp == N_EXPR_STACK-1)                 \
273172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            return -1;                             \
273272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         sp++;                                     \
273372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         stack[sp] = (_arg);                       \
273472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      } while (0)
273572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
273672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj#  define POP(_lval)                               \
273772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      do {                                         \
273872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         vg_assert(sp >= -1 && sp < N_EXPR_STACK); \
273972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         if (sp == -1)                             \
274072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            return -1;                             \
274172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         _lval = stack[sp];                        \
274272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         sp--;                                     \
274372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      } while (0)
274472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
2745f6716dd8f025c9ace67541f3360d7f4523496d8atom   Int      ix, ix2, reg;
2746f6716dd8f025c9ace67541f3360d7f4523496d8atom   UChar    opcode;
2747f6716dd8f025c9ace67541f3360d7f4523496d8atom   Word     sw;
2748f6716dd8f025c9ace67541f3360d7f4523496d8atom   UWord    uw;
274940628facff2285b0fce592381c6e26fdcd2a1252tom   CfiUnop  uop;
2750f6716dd8f025c9ace67541f3360d7f4523496d8atom   CfiBinop bop;
27516bd9dc18c043927c1196caba20a327238a179c42florian   const HChar* opname;
275272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
275372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   Int sp; /* # of top element: valid is -1 .. N_EXPR_STACK-1 */
275472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   Int stack[N_EXPR_STACK];  /* indices into ctx->exprs */
2755518850bf0da07ed3e2244e307268ae0fd80e93a8florian   const struct UnwindContextState* ctxs = &ctx->state[ctx->state_sp];
275672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
27575d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   XArray*  dst   = ctx->exprs;
27585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiCursor limit = ML_(cur_plus)(expr, exprlen);
275972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
276072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   vg_assert(dst);
276172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   vg_assert(exprlen >= 0);
276272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
276372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   sp = -1; /* empty */
276472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
276572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   /* Synthesise the CFA as a CfiExpr */
276672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   if (push_cfa_at_start) {
2767de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      if (ctxs->cfa_is_regoff) {
276872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         /* cfa is reg +/- offset */
276972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         ix = ML_(CfiExpr_Binop)( dst,
2770f6716dd8f025c9ace67541f3360d7f4523496d8atom                 Cbinop_Add,
2771de1b03da8168ecaa16d0fa05f83066f334c6948esewardj                 ML_(CfiExpr_DwReg)( dst, ctxs->cfa_reg ),
2772de1b03da8168ecaa16d0fa05f83066f334c6948esewardj                 ML_(CfiExpr_Const)( dst, (UWord)(Word)ctxs->cfa_off )
277372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj              );
277472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         PUSH(ix);
277572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      } else {
277672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         /* CFA is already an expr; use its root node */
2777de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         PUSH(ctxs->cfa_expr_ix);
277872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      }
277972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   }
278072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
278172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   while (True) {
278272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
278372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      vg_assert(sp >= -1 && sp < N_EXPR_STACK);
278472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
27855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      if (ML_(cur_cmpGT)(expr, limit)) /* "expr > limit" */
278672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         return -1;  /* overrun - something's wrong */
278772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
27885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      if (ML_(cur_cmpEQ)(expr, limit)) { /* "expr == limit" */
278972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj        /* end of expr - return expr on the top of stack. */
279072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj        if (sp == -1)
279172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj           return -1; /* stack empty.  Bad. */
279272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj        else
279372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj           break;
279472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      }
279572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
279640628facff2285b0fce592381c6e26fdcd2a1252tom      uop = 0; bop = 0; opname = NULL; /* excessively conservative */
279719dc88f90d0e19a1463797dd99f6792a42f961d3sewardj
27985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      opcode = ML_(cur_step_UChar)(&expr);
279972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      switch (opcode) {
280072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
280119dc88f90d0e19a1463797dd99f6792a42f961d3sewardj         case DW_OP_lit0 ... DW_OP_lit31:
280219dc88f90d0e19a1463797dd99f6792a42f961d3sewardj            /* push: literal 0 .. 31 */
280319dc88f90d0e19a1463797dd99f6792a42f961d3sewardj            sw = (Word)opcode - (Word)DW_OP_lit0;
280419dc88f90d0e19a1463797dd99f6792a42f961d3sewardj            vg_assert(sw >= 0 && sw <= 31);
280519dc88f90d0e19a1463797dd99f6792a42f961d3sewardj            PUSH( ML_(CfiExpr_Const)( dst, (UWord)sw ) );
280619dc88f90d0e19a1463797dd99f6792a42f961d3sewardj            if (ddump_frames)
280719dc88f90d0e19a1463797dd99f6792a42f961d3sewardj               VG_(printf)("DW_OP_lit%ld", sw);
280819dc88f90d0e19a1463797dd99f6792a42f961d3sewardj            break;
280919dc88f90d0e19a1463797dd99f6792a42f961d3sewardj
281072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         case DW_OP_breg0 ... DW_OP_breg31:
281172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            /* push: reg + sleb128 */
281272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            reg = (Int)opcode - (Int)DW_OP_breg0;
281372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            vg_assert(reg >= 0 && reg <= 31);
28145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            sw = step_leb128S( &expr );
281572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            ix = ML_(CfiExpr_Binop)( dst,
2816f6716dd8f025c9ace67541f3360d7f4523496d8atom                    Cbinop_Add,
281772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj                    ML_(CfiExpr_DwReg)( dst, reg ),
281872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj                    ML_(CfiExpr_Const)( dst, (UWord)sw )
281972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj                 );
282072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            PUSH(ix);
282172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            if (ddump_frames)
282272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj               VG_(printf)("DW_OP_breg%d: %ld", reg, sw);
282372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            break;
282472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
282513596ffd2407e45060ce430dfe087ac44ad4d22esewardj         case DW_OP_reg0 ... DW_OP_reg31:
282613596ffd2407e45060ce430dfe087ac44ad4d22esewardj            /* push: reg */
282713596ffd2407e45060ce430dfe087ac44ad4d22esewardj            reg = (Int)opcode - (Int)DW_OP_reg0;
282813596ffd2407e45060ce430dfe087ac44ad4d22esewardj            vg_assert(reg >= 0 && reg <= 31);
282913596ffd2407e45060ce430dfe087ac44ad4d22esewardj            ix = ML_(CfiExpr_DwReg)( dst, reg );
283013596ffd2407e45060ce430dfe087ac44ad4d22esewardj            PUSH(ix);
283113596ffd2407e45060ce430dfe087ac44ad4d22esewardj            if (ddump_frames)
283213596ffd2407e45060ce430dfe087ac44ad4d22esewardj               VG_(printf)("DW_OP_reg%d", reg);
283313596ffd2407e45060ce430dfe087ac44ad4d22esewardj            break;
283413596ffd2407e45060ce430dfe087ac44ad4d22esewardj
2835c153bf6a502f49184c61af3ae779a09d50c15359sewardj         case DW_OP_plus_uconst:
28365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            uw = step_leb128U( &expr );
2837c153bf6a502f49184c61af3ae779a09d50c15359sewardj            PUSH( ML_(CfiExpr_Const)( dst, uw ) );
2838c153bf6a502f49184c61af3ae779a09d50c15359sewardj            POP( ix );
2839c153bf6a502f49184c61af3ae779a09d50c15359sewardj            POP( ix2 );
2840f6716dd8f025c9ace67541f3360d7f4523496d8atom            PUSH( ML_(CfiExpr_Binop)( dst, Cbinop_Add, ix2, ix ) );
2841c153bf6a502f49184c61af3ae779a09d50c15359sewardj            if (ddump_frames)
2842c153bf6a502f49184c61af3ae779a09d50c15359sewardj               VG_(printf)("DW_OP_plus_uconst: %lu", uw);
2843c153bf6a502f49184c61af3ae779a09d50c15359sewardj            break;
2844c153bf6a502f49184c61af3ae779a09d50c15359sewardj
284572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         case DW_OP_const4s:
284672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            /* push: 32-bit signed immediate */
28475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            sw = step_le_s_encoded_literal( &expr, 4 );
284872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            PUSH( ML_(CfiExpr_Const)( dst, (UWord)sw ) );
284972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            if (ddump_frames)
285072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj               VG_(printf)("DW_OP_const4s: %ld", sw);
285172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            break;
285272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
285340628facff2285b0fce592381c6e26fdcd2a1252tom         case DW_OP_const2s:
285440628facff2285b0fce592381c6e26fdcd2a1252tom            /* push: 16-bit signed immediate */
28555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            sw = step_le_s_encoded_literal( &expr, 2 );
285640628facff2285b0fce592381c6e26fdcd2a1252tom            PUSH( ML_(CfiExpr_Const)( dst, (UWord)sw ) );
285740628facff2285b0fce592381c6e26fdcd2a1252tom            if (ddump_frames)
285840628facff2285b0fce592381c6e26fdcd2a1252tom               VG_(printf)("DW_OP_const2s: %ld", sw);
285940628facff2285b0fce592381c6e26fdcd2a1252tom            break;
286040628facff2285b0fce592381c6e26fdcd2a1252tom
286113596ffd2407e45060ce430dfe087ac44ad4d22esewardj         case DW_OP_const1s:
286213596ffd2407e45060ce430dfe087ac44ad4d22esewardj            /* push: 8-bit signed immediate */
28635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            sw = step_le_s_encoded_literal( &expr, 1 );
286413596ffd2407e45060ce430dfe087ac44ad4d22esewardj            PUSH( ML_(CfiExpr_Const)( dst, (UWord)sw ) );
286513596ffd2407e45060ce430dfe087ac44ad4d22esewardj            if (ddump_frames)
286613596ffd2407e45060ce430dfe087ac44ad4d22esewardj               VG_(printf)("DW_OP_const1s: %ld", sw);
286713596ffd2407e45060ce430dfe087ac44ad4d22esewardj            break;
286813596ffd2407e45060ce430dfe087ac44ad4d22esewardj
286940628facff2285b0fce592381c6e26fdcd2a1252tom         case DW_OP_const1u:
287040628facff2285b0fce592381c6e26fdcd2a1252tom            /* push: 8-bit unsigned immediate */
28715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            uw = step_le_u_encoded_literal( &expr, 1 );
287240628facff2285b0fce592381c6e26fdcd2a1252tom            PUSH( ML_(CfiExpr_Const)( dst, uw ) );
287340628facff2285b0fce592381c6e26fdcd2a1252tom            if (ddump_frames)
287440628facff2285b0fce592381c6e26fdcd2a1252tom               VG_(printf)("DW_OP_const1: %lu", uw);
287540628facff2285b0fce592381c6e26fdcd2a1252tom            break;
287640628facff2285b0fce592381c6e26fdcd2a1252tom
287740628facff2285b0fce592381c6e26fdcd2a1252tom         case DW_OP_const2u:
287840628facff2285b0fce592381c6e26fdcd2a1252tom            /* push: 16-bit unsigned immediate */
28795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            uw = step_le_u_encoded_literal( &expr, 2 );
288040628facff2285b0fce592381c6e26fdcd2a1252tom            PUSH( ML_(CfiExpr_Const)( dst, uw ) );
288140628facff2285b0fce592381c6e26fdcd2a1252tom            if (ddump_frames)
288240628facff2285b0fce592381c6e26fdcd2a1252tom               VG_(printf)("DW_OP_const2: %lu", uw);
288340628facff2285b0fce592381c6e26fdcd2a1252tom            break;
288440628facff2285b0fce592381c6e26fdcd2a1252tom
288540628facff2285b0fce592381c6e26fdcd2a1252tom         case DW_OP_const4u:
288640628facff2285b0fce592381c6e26fdcd2a1252tom            /* push: 32-bit unsigned immediate */
28875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            uw = step_le_u_encoded_literal( &expr, 4 );
288840628facff2285b0fce592381c6e26fdcd2a1252tom            PUSH( ML_(CfiExpr_Const)( dst, uw ) );
288940628facff2285b0fce592381c6e26fdcd2a1252tom            if (ddump_frames)
289040628facff2285b0fce592381c6e26fdcd2a1252tom               VG_(printf)("DW_OP_const4: %lu", uw);
289140628facff2285b0fce592381c6e26fdcd2a1252tom            break;
289240628facff2285b0fce592381c6e26fdcd2a1252tom
289340628facff2285b0fce592381c6e26fdcd2a1252tom         case DW_OP_abs:
289440628facff2285b0fce592381c6e26fdcd2a1252tom            uop = Cunop_Abs; opname = "abs"; goto unop;
289540628facff2285b0fce592381c6e26fdcd2a1252tom         case DW_OP_neg:
289640628facff2285b0fce592381c6e26fdcd2a1252tom            uop = Cunop_Neg; opname = "neg"; goto unop;
289740628facff2285b0fce592381c6e26fdcd2a1252tom         case DW_OP_not:
289840628facff2285b0fce592381c6e26fdcd2a1252tom            uop = Cunop_Not; opname = "not"; goto unop;
289940628facff2285b0fce592381c6e26fdcd2a1252tom         unop:
290040628facff2285b0fce592381c6e26fdcd2a1252tom            POP( ix );
290140628facff2285b0fce592381c6e26fdcd2a1252tom            PUSH( ML_(CfiExpr_Unop)( dst, uop, ix ) );
290240628facff2285b0fce592381c6e26fdcd2a1252tom            if (ddump_frames)
290340628facff2285b0fce592381c6e26fdcd2a1252tom               VG_(printf)("DW_OP_%s", opname);
290440628facff2285b0fce592381c6e26fdcd2a1252tom            break;
290540628facff2285b0fce592381c6e26fdcd2a1252tom
290672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         case DW_OP_minus:
2907f6716dd8f025c9ace67541f3360d7f4523496d8atom            bop = Cbinop_Sub; opname = "minus"; goto binop;
290872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         case DW_OP_plus:
2909f6716dd8f025c9ace67541f3360d7f4523496d8atom            bop = Cbinop_Add; opname = "plus"; goto binop;
291019dc88f90d0e19a1463797dd99f6792a42f961d3sewardj         case DW_OP_and:
2911f6716dd8f025c9ace67541f3360d7f4523496d8atom            bop = Cbinop_And; opname = "and"; goto binop;
29127888e2204fff6e7429236b4227ed16594e7743b9sewardj         case DW_OP_mul:
2913f6716dd8f025c9ace67541f3360d7f4523496d8atom            bop = Cbinop_Mul; opname = "mul"; goto binop;
29140b98239b3e0abd430dbc913454d63c7e3d8c8b12tom         case DW_OP_shl:
2915f6716dd8f025c9ace67541f3360d7f4523496d8atom            bop = Cbinop_Shl; opname = "shl"; goto binop;
29160b98239b3e0abd430dbc913454d63c7e3d8c8b12tom         case DW_OP_shr:
2917f6716dd8f025c9ace67541f3360d7f4523496d8atom            bop = Cbinop_Shr; opname = "shr"; goto binop;
29180b98239b3e0abd430dbc913454d63c7e3d8c8b12tom         case DW_OP_eq:
2919f6716dd8f025c9ace67541f3360d7f4523496d8atom            bop = Cbinop_Eq; opname = "eq"; goto binop;
29200b98239b3e0abd430dbc913454d63c7e3d8c8b12tom         case DW_OP_ge:
2921f6716dd8f025c9ace67541f3360d7f4523496d8atom            bop = Cbinop_Ge; opname = "ge"; goto binop;
29220b98239b3e0abd430dbc913454d63c7e3d8c8b12tom         case DW_OP_gt:
2923f6716dd8f025c9ace67541f3360d7f4523496d8atom            bop = Cbinop_Gt; opname = "gt"; goto binop;
29240b98239b3e0abd430dbc913454d63c7e3d8c8b12tom         case DW_OP_le:
2925f6716dd8f025c9ace67541f3360d7f4523496d8atom            bop = Cbinop_Le; opname = "le"; goto binop;
29260b98239b3e0abd430dbc913454d63c7e3d8c8b12tom         case DW_OP_lt:
2927f6716dd8f025c9ace67541f3360d7f4523496d8atom            bop = Cbinop_Lt; opname = "lt"; goto binop;
29280b98239b3e0abd430dbc913454d63c7e3d8c8b12tom         case DW_OP_ne:
2929f6716dd8f025c9ace67541f3360d7f4523496d8atom            bop = Cbinop_Ne; opname = "ne"; goto binop;
293019dc88f90d0e19a1463797dd99f6792a42f961d3sewardj         binop:
293172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            POP( ix );
293272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            POP( ix2 );
2933f6716dd8f025c9ace67541f3360d7f4523496d8atom            PUSH( ML_(CfiExpr_Binop)( dst, bop, ix2, ix ) );
293472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            if (ddump_frames)
293519dc88f90d0e19a1463797dd99f6792a42f961d3sewardj               VG_(printf)("DW_OP_%s", opname);
293672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            break;
293772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
2938bd7aca648dd9ee152dbdc4474b533a55e543514csewardj         case DW_OP_deref:
2939bd7aca648dd9ee152dbdc4474b533a55e543514csewardj            POP( ix );
2940bd7aca648dd9ee152dbdc4474b533a55e543514csewardj            PUSH( ML_(CfiExpr_Deref)( dst, ix ) );
2941bd7aca648dd9ee152dbdc4474b533a55e543514csewardj            if (ddump_frames)
2942bd7aca648dd9ee152dbdc4474b533a55e543514csewardj               VG_(printf)("DW_OP_deref");
2943bd7aca648dd9ee152dbdc4474b533a55e543514csewardj            break;
2944bd7aca648dd9ee152dbdc4474b533a55e543514csewardj
294572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         default:
29467888e2204fff6e7429236b4227ed16594e7743b9sewardj            if (!VG_(clo_xml))
29477888e2204fff6e7429236b4227ed16594e7743b9sewardj               VG_(message)(Vg_DebugMsg,
29481ff57e6a7669ea9ccebd7cc8883e02b477e8597bsewardj                            "Warning: DWARF2 CFI reader: unhandled DW_OP_ "
2949738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                            "opcode 0x%x\n", (Int)opcode);
295072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            return -1;
295172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      }
295272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
29535d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      if (ML_(cur_cmpLT)(expr, limit) && ddump_frames)
295472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         VG_(printf)("; ");
295572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
295672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   }
295772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
295872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   vg_assert(sp >= -1 && sp < N_EXPR_STACK);
295972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   if (sp == -1)
296072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      return -1;
296172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
296272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   if (0 && ddump_frames)
296372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      ML_(ppCfiExpr)( dst, stack[sp] );
296472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj   return stack[sp];
296572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
296672427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj#  undef POP
296772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj#  undef PUSH
296872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj#  undef N_EXPR_STACK
296972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj}
297072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
297172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
297255022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj/* ------------ Run/show CFI instructions ------------ */
297355022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
29745c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj/* Run a CFI instruction, and also return its length.
29755c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   Returns 0 if the instruction could not be executed.
29765c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj*/
29775c638c2bda665e232ecf62b5443c93c3d6b7e06asewardjstatic Int run_CF_instruction ( /*MOD*/UnwindContext* ctx,
29785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                DiCursor instrIN,
2979518850bf0da07ed3e2244e307268ae0fd80e93a8florian                                const UnwindContext* restore_ctx,
2980518850bf0da07ed3e2244e307268ae0fd80e93a8florian                                const AddressDecodingInfo* adi,
2981518850bf0da07ed3e2244e307268ae0fd80e93a8florian                                const DebugInfo* di )
29825c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj{
29835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   Int      off, reg, reg2, len, j;
29845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UInt     delta;
29855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   Addr     printing_bias = ((Addr)ctx->initloc) - ((Addr)di->text_bias);
2986de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   struct UnwindContextState* ctxs;
29875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
29885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiCursor instr   = instrIN;
29895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UChar    instr_0 = ML_(cur_step_UChar)(&instr);
29905d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UChar    hi2     = (instr_0 >> 6) & 3;
29915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UChar    lo6     = instr_0 & 0x3F;
29925c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
2993de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   if (ctx->state_sp < 0 || ctx->state_sp >= N_RR_STACK)
29943d026b18e0b41e5f13336f1997054f56cbd89da0sewardj      return 0; /* bogus reg-rule stack pointer */
29953d026b18e0b41e5f13336f1997054f56cbd89da0sewardj
2996de1b03da8168ecaa16d0fa05f83066f334c6948esewardj   ctxs = &ctx->state[ctx->state_sp];
29975c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   if (hi2 == DW_CFA_advance_loc) {
29985c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      delta = (UInt)lo6;
2999987a765d9c5be7da6832aed3a22786520867137fsewardj      delta *= ctx->code_a_f;
30005c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      ctx->loc += delta;
3001b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (di->ddump_frames)
30023646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  DW_CFA_advance_loc: %d to %08lx\n",
30033646a495f974e4aacf329e7539a0d584962ff6f6sewardj                     (Int)delta, (Addr)ctx->loc + printing_bias);
30045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      return ML_(cur_minus)(instr, instrIN);
30055c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   }
30065c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
30075c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   if (hi2 == DW_CFA_offset) {
300872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj      /* Set rule for reg 'lo6' to CFAOff(off * data_af) */
30095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      off = step_leb128( &instr, 0 );
30105c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      reg = (Int)lo6;
30115c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      if (reg < 0 || reg >= N_CFI_REGS)
30125c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         return 0; /* fail */
3013de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      ctxs->reg[reg].tag = RR_CFAOff;
3014de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      ctxs->reg[reg].arg = off * ctx->data_a_f;
3015b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (di->ddump_frames)
30163646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  DW_CFA_offset: r%d at cfa%s%d\n",
30173d026b18e0b41e5f13336f1997054f56cbd89da0sewardj                     (Int)reg,
3018de1b03da8168ecaa16d0fa05f83066f334c6948esewardj                     ctxs->reg[reg].arg < 0 ? "" : "+",
3019de1b03da8168ecaa16d0fa05f83066f334c6948esewardj                     (Int)ctxs->reg[reg].arg );
30205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      return ML_(cur_minus)(instr, instrIN);
30215c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   }
30225c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
30235c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   if (hi2 == DW_CFA_restore) {
30248eb413204b3d80f52d207e8292c952f74faa2ca6sewardj      reg = (Int)lo6;
30258eb413204b3d80f52d207e8292c952f74faa2ca6sewardj      if (reg < 0 || reg >= N_CFI_REGS)
30268eb413204b3d80f52d207e8292c952f74faa2ca6sewardj         return 0; /* fail */
30278eb413204b3d80f52d207e8292c952f74faa2ca6sewardj      if (restore_ctx == NULL)
30288eb413204b3d80f52d207e8292c952f74faa2ca6sewardj         return 0; /* fail */
3029de1b03da8168ecaa16d0fa05f83066f334c6948esewardj      ctxs->reg[reg] = restore_ctx->state[restore_ctx->state_sp].reg[reg];
3030b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (di->ddump_frames)
3031687bbf6d72a26d7f7f35f672a67ca2bbe1455a8dsewardj         VG_(printf)("  DW_CFA_restore: r%d\n", (Int)reg);
30325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      return ML_(cur_minus)(instr, instrIN);
30335c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   }
30345c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
30355c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   vg_assert(hi2 == DW_CFA_use_secondary);
30365c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
30375c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   switch (lo6) {
30385c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      case DW_CFA_nop:
3039b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
30403646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  DW_CFA_nop\n");
30415c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         break;
30422fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_CFA_set_loc:
30431936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj         /* WAS:
30441936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj            ctx->loc = read_Addr(&instr[i]) - ctx->initloc; i+= sizeof(Addr);
30451936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj            Was this ever right? */
3046ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj         /* 2007 Feb 23: No.  binutils/dwarf.c treats it as an encoded
3047ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj            address and that appears to be in accordance with the
3048ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj            DWARF3 spec. */
30495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ctx->loc = step_encoded_Addr(adi, &instr);
3050b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
30513646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  rci:DW_CFA_set_loc\n");
30522fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         break;
30535c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      case DW_CFA_advance_loc1:
30545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         delta = (UInt)ML_(cur_step_UChar)(&instr);
3055987a765d9c5be7da6832aed3a22786520867137fsewardj         delta *= ctx->code_a_f;
30562fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         ctx->loc += delta;
3057b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
3058687bbf6d72a26d7f7f35f672a67ca2bbe1455a8dsewardj            VG_(printf)("  DW_CFA_advance_loc1: %d to %08lx\n",
3059687bbf6d72a26d7f7f35f672a67ca2bbe1455a8dsewardj                        (Int)delta, (Addr)ctx->loc + printing_bias);
30602fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         break;
30612fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_CFA_advance_loc2:
30625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         delta = (UInt)ML_(cur_step_UShort)(&instr);
3063987a765d9c5be7da6832aed3a22786520867137fsewardj         delta *= ctx->code_a_f;
30642fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         ctx->loc += delta;
3065b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
3066687bbf6d72a26d7f7f35f672a67ca2bbe1455a8dsewardj            VG_(printf)("  DW_CFA_advance_loc2: %d to %08lx\n",
3067687bbf6d72a26d7f7f35f672a67ca2bbe1455a8dsewardj                        (Int)delta, (Addr)ctx->loc + printing_bias);
30682fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         break;
30692fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_CFA_advance_loc4:
30705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         delta = (UInt)ML_(cur_step_UInt)(&instr);
3071987a765d9c5be7da6832aed3a22786520867137fsewardj         delta *= ctx->code_a_f;
30722fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         ctx->loc += delta;
3073b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
3074687bbf6d72a26d7f7f35f672a67ca2bbe1455a8dsewardj            VG_(printf)("  DW_CFA_advance_loc4: %d to %08lx\n",
3075687bbf6d72a26d7f7f35f672a67ca2bbe1455a8dsewardj                        (Int)delta, (Addr)ctx->loc + printing_bias);
30765c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         break;
30775c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
30785c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      case DW_CFA_def_cfa:
30795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0 );
30805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         off = step_leb128( &instr, 0 );
30815c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         if (reg < 0 || reg >= N_CFI_REGS)
30825c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj            return 0; /* fail */
3083de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_is_regoff = True;
3084de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_expr_ix   = 0;
3085de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_reg       = reg;
3086de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_off       = off;
3087b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
30883646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  DW_CFA_def_cfa: r%d ofs %d\n", (Int)reg, (Int)off);
30895c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         break;
30905c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
3091d69222cb20119a410b777665e16873a2391f9344sewardj      case DW_CFA_def_cfa_sf:
30925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0 );
30935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         off = step_leb128( &instr, 1 );
3094d69222cb20119a410b777665e16873a2391f9344sewardj         if (reg < 0 || reg >= N_CFI_REGS)
3095d69222cb20119a410b777665e16873a2391f9344sewardj            return 0; /* fail */
3096de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_is_regoff = True;
3097de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_expr_ix   = 0;
3098de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_reg       = reg;
3099de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_off       = off * ctx->data_a_f;
3100b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
31013646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  rci:DW_CFA_def_cfa_sf\n");
3102d69222cb20119a410b777665e16873a2391f9344sewardj         break;
3103d69222cb20119a410b777665e16873a2391f9344sewardj
3104e0707a69816ce68deed8de3c7edd940cb4750662sewardj      case DW_CFA_register:
31055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg  = step_leb128( &instr, 0 );
31065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg2 = step_leb128( &instr, 0 );
3107e0707a69816ce68deed8de3c7edd940cb4750662sewardj         if (reg < 0 || reg >= N_CFI_REGS)
3108e0707a69816ce68deed8de3c7edd940cb4750662sewardj            return 0; /* fail */
3109e0707a69816ce68deed8de3c7edd940cb4750662sewardj         if (reg2 < 0 || reg2 >= N_CFI_REGS)
3110e0707a69816ce68deed8de3c7edd940cb4750662sewardj            return 0; /* fail */
3111de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].tag = RR_Reg;
3112de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].arg = reg2;
3113b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
311472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            VG_(printf)("  DW_CFA_register: r%d in r%d\n",
311572427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj                        (Int)reg, (Int)reg2);
3116e0707a69816ce68deed8de3c7edd940cb4750662sewardj         break;
3117e0707a69816ce68deed8de3c7edd940cb4750662sewardj
3118d69222cb20119a410b777665e16873a2391f9344sewardj      case DW_CFA_offset_extended:
31195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0 );
31205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         off = step_leb128( &instr, 0 );
3121d69222cb20119a410b777665e16873a2391f9344sewardj         if (reg < 0 || reg >= N_CFI_REGS)
3122d69222cb20119a410b777665e16873a2391f9344sewardj            return 0; /* fail */
3123de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].tag = RR_CFAOff;
3124de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].arg = off * ctx->data_a_f;
3125b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
31263646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  rci:DW_CFA_offset_extended\n");
3127d69222cb20119a410b777665e16873a2391f9344sewardj         break;
3128d69222cb20119a410b777665e16873a2391f9344sewardj
3129325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj      case DW_CFA_offset_extended_sf:
31305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0 );
31315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         off = step_leb128( &instr, 1 );
3132325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj         if (reg < 0 || reg >= N_CFI_REGS)
3133325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj            return 0; /* fail */
3134de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].tag = RR_CFAOff;
3135de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].arg = off * ctx->data_a_f;
3136b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
3137ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj            VG_(printf)("  DW_CFA_offset_extended_sf: r%d at cfa%s%d\n",
31383d026b18e0b41e5f13336f1997054f56cbd89da0sewardj                        reg,
3139de1b03da8168ecaa16d0fa05f83066f334c6948esewardj                        ctxs->reg[reg].arg < 0 ? "" : "+",
3140de1b03da8168ecaa16d0fa05f83066f334c6948esewardj                        (Int)ctxs->reg[reg].arg);
3141ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj         break;
3142325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj
3143d69222cb20119a410b777665e16873a2391f9344sewardj      case DW_CFA_GNU_negative_offset_extended:
31445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0 );
31455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         off = step_leb128( &instr, 0 );
3146d69222cb20119a410b777665e16873a2391f9344sewardj         if (reg < 0 || reg >= N_CFI_REGS)
3147d69222cb20119a410b777665e16873a2391f9344sewardj            return 0; /* fail */
3148de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].tag = RR_CFAOff;
3149de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].arg = (-off) * ctx->data_a_f;
3150b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
31513646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  rci:DW_CFA_GNU_negative_offset_extended\n");
3152d69222cb20119a410b777665e16873a2391f9344sewardj         break;
3153d69222cb20119a410b777665e16873a2391f9344sewardj
3154d69222cb20119a410b777665e16873a2391f9344sewardj      case DW_CFA_restore_extended:
31555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0 );
3156d69222cb20119a410b777665e16873a2391f9344sewardj         if (reg < 0 || reg >= N_CFI_REGS)
3157d69222cb20119a410b777665e16873a2391f9344sewardj            return 0; /* fail */
3158d69222cb20119a410b777665e16873a2391f9344sewardj	 if (restore_ctx == NULL)
3159d69222cb20119a410b777665e16873a2391f9344sewardj	    return 0; /* fail */
3160de1b03da8168ecaa16d0fa05f83066f334c6948esewardj	 ctxs->reg[reg] = restore_ctx->state[restore_ctx->state_sp].reg[reg];
3161b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
31623646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  rci:DW_CFA_restore_extended\n");
3163d69222cb20119a410b777665e16873a2391f9344sewardj         break;
3164d69222cb20119a410b777665e16873a2391f9344sewardj
3165d69222cb20119a410b777665e16873a2391f9344sewardj      case DW_CFA_val_offset:
31665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0 );
31675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         off = step_leb128( &instr, 0 );
3168d69222cb20119a410b777665e16873a2391f9344sewardj         if (reg < 0 || reg >= N_CFI_REGS)
3169d69222cb20119a410b777665e16873a2391f9344sewardj            return 0; /* fail */
3170de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].tag = RR_CFAValOff;
3171de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].arg = off * ctx->data_a_f;
3172b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
31733646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  rci:DW_CFA_val_offset\n");
3174d69222cb20119a410b777665e16873a2391f9344sewardj         break;
3175d69222cb20119a410b777665e16873a2391f9344sewardj
3176d69222cb20119a410b777665e16873a2391f9344sewardj      case DW_CFA_val_offset_sf:
31775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0 );
31785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         off = step_leb128( &instr, 1 );
3179d69222cb20119a410b777665e16873a2391f9344sewardj         if (reg < 0 || reg >= N_CFI_REGS)
3180d69222cb20119a410b777665e16873a2391f9344sewardj            return 0; /* fail */
3181de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].tag = RR_CFAValOff;
3182de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].arg = off * ctx->data_a_f;
3183b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
31843646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  rci:DW_CFA_val_offset_sf\n");
3185d69222cb20119a410b777665e16873a2391f9344sewardj         break;
3186d69222cb20119a410b777665e16873a2391f9344sewardj
3187325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj      case DW_CFA_def_cfa_register:
31885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0);
31895c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         if (reg < 0 || reg >= N_CFI_REGS)
31905c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj            return 0; /* fail */
3191de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_is_regoff = True;
3192de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_expr_ix   = 0;
3193de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_reg       = reg;
319472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         /* ->cfa_off unchanged */
3195b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
3196987a765d9c5be7da6832aed3a22786520867137fsewardj            VG_(printf)("  DW_CFA_def_cfa_register: r%d\n", (Int)reg );
31975c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         break;
3198325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj
3199325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj      case DW_CFA_def_cfa_offset:
32005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         off = step_leb128( &instr, 0);
3201de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_is_regoff = True;
3202de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_expr_ix   = 0;
320372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         /* ->reg is unchanged */
3204de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_off       = off;
3205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
32063646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  DW_CFA_def_cfa_offset: %d\n", (Int)off);
32075c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         break;
3208325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj
3209ab30d209064d9ed84d8a218e627f5a1345e9d30bsewardj      case DW_CFA_def_cfa_offset_sf:
32105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         off = step_leb128( &instr, 1);
3211de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_is_regoff = True;
3212de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_expr_ix   = 0;
321372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         /* ->reg is unchanged */
3214de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_off       = off * ctx->data_a_f;
3215b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
3216de1b03da8168ecaa16d0fa05f83066f334c6948esewardj            VG_(printf)("  DW_CFA_def_cfa_offset_sf: %d\n", ctxs->cfa_off);
3217ab30d209064d9ed84d8a218e627f5a1345e9d30bsewardj         break;
3218ab30d209064d9ed84d8a218e627f5a1345e9d30bsewardj
3219301901f43437bbf2b02d0df49f6bcfde27485936sewardj      case DW_CFA_undefined:
32205d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0);
3221301901f43437bbf2b02d0df49f6bcfde27485936sewardj         if (reg < 0 || reg >= N_CFI_REGS)
3222301901f43437bbf2b02d0df49f6bcfde27485936sewardj            return 0; /* fail */
3223de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].tag = RR_Undef;
3224de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].arg = 0;
3225b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
32263646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  rci:DW_CFA_undefined\n");
3227301901f43437bbf2b02d0df49f6bcfde27485936sewardj         break;
3228301901f43437bbf2b02d0df49f6bcfde27485936sewardj
322980b8b09c2b5107b955909a89f15e1f88852e7bc6tom      case DW_CFA_same_value:
32305d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0);
323180b8b09c2b5107b955909a89f15e1f88852e7bc6tom         if (reg < 0 || reg >= N_CFI_REGS)
323280b8b09c2b5107b955909a89f15e1f88852e7bc6tom            return 0; /* fail */
3233de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].tag = RR_Same;
3234de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].arg = 0;
323580b8b09c2b5107b955909a89f15e1f88852e7bc6tom         if (di->ddump_frames)
323680b8b09c2b5107b955909a89f15e1f88852e7bc6tom            VG_(printf)("  rci:DW_CFA_same_value\n");
323780b8b09c2b5107b955909a89f15e1f88852e7bc6tom         break;
323880b8b09c2b5107b955909a89f15e1f88852e7bc6tom
3239325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj      case DW_CFA_GNU_args_size:
32405c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         /* No idea what is supposed to happen.  gdb-6.3 simply
32415c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj            ignores these. */
32425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         /*off = */ (void)step_leb128( &instr, 0 );
3243b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
32443646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  rci:DW_CFA_GNU_args_size (ignored)\n");
32455c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         break;
3246325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj
32475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      case DW_CFA_expression: {
324819dc88f90d0e19a1463797dd99f6792a42f961d3sewardj         /* Identical to DW_CFA_val_expression except that the value
324919dc88f90d0e19a1463797dd99f6792a42f961d3sewardj            computed is an address and so needs one final
325019dc88f90d0e19a1463797dd99f6792a42f961d3sewardj            dereference. */
32515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor expr;
32525d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0 );
32535d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         len = step_leb128( &instr, 0 );
32545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         expr = instr;
32555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         instr = ML_(cur_plus)(instr, len);
325619dc88f90d0e19a1463797dd99f6792a42f961d3sewardj         if (reg < 0 || reg >= N_CFI_REGS)
32571e601fe35a89c584cb028b92b000a89d573181c8sewardj            return 0; /* fail */
3258b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
325919dc88f90d0e19a1463797dd99f6792a42f961d3sewardj            VG_(printf)("  DW_CFA_expression: r%d (",
326019dc88f90d0e19a1463797dd99f6792a42f961d3sewardj                        (Int)reg);
326119dc88f90d0e19a1463797dd99f6792a42f961d3sewardj         /* Convert the expression into a dag rooted at ctx->exprs index j,
326219dc88f90d0e19a1463797dd99f6792a42f961d3sewardj            or fail. */
326319dc88f90d0e19a1463797dd99f6792a42f961d3sewardj         j = dwarfexpr_to_dag ( ctx, expr, len, True/*push CFA at start*/,
3264b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                di->ddump_frames);
3265b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
326619dc88f90d0e19a1463797dd99f6792a42f961d3sewardj            VG_(printf)(")\n");
326719dc88f90d0e19a1463797dd99f6792a42f961d3sewardj         vg_assert(j >= -1);
326819dc88f90d0e19a1463797dd99f6792a42f961d3sewardj         if (j >= 0) {
326919dc88f90d0e19a1463797dd99f6792a42f961d3sewardj            vg_assert(ctx->exprs);
327019dc88f90d0e19a1463797dd99f6792a42f961d3sewardj            vg_assert( j < VG_(sizeXA)(ctx->exprs) );
327119dc88f90d0e19a1463797dd99f6792a42f961d3sewardj         }
327219dc88f90d0e19a1463797dd99f6792a42f961d3sewardj         if (j == -1)
327319dc88f90d0e19a1463797dd99f6792a42f961d3sewardj            return 0; /* fail */
327419dc88f90d0e19a1463797dd99f6792a42f961d3sewardj         /* Add an extra dereference */
327519dc88f90d0e19a1463797dd99f6792a42f961d3sewardj         j = ML_(CfiExpr_Deref)( ctx->exprs, j );
3276de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].tag = RR_ValExpr;
3277de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].arg = j;
32781e601fe35a89c584cb028b92b000a89d573181c8sewardj         break;
32795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      }
32801e601fe35a89c584cb028b92b000a89d573181c8sewardj
32815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      case DW_CFA_val_expression: {
32825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor expr;
32835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0 );
32845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         len = step_leb128( &instr, 0 );
32855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         expr = instr;
32865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         instr = ML_(cur_plus)(instr, len);
3287d69222cb20119a410b777665e16873a2391f9344sewardj         if (reg < 0 || reg >= N_CFI_REGS)
3288d69222cb20119a410b777665e16873a2391f9344sewardj            return 0; /* fail */
3289b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
329072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            VG_(printf)("  DW_CFA_val_expression: r%d (",
3291687bbf6d72a26d7f7f35f672a67ca2bbe1455a8dsewardj                        (Int)reg);
329272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         /* Convert the expression into a dag rooted at ctx->exprs index j,
329372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            or fail. */
329472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         j = dwarfexpr_to_dag ( ctx, expr, len, True/*push CFA at start*/,
3295b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                di->ddump_frames);
3296b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
329772427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            VG_(printf)(")\n");
329872427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         vg_assert(j >= -1);
329972427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         if (j >= 0) {
330072427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            vg_assert(ctx->exprs);
330172427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            vg_assert( j < VG_(sizeXA)(ctx->exprs) );
330272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         }
330372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         if (j == -1)
330472427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj            return 0; /* fail */
3305de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].tag = RR_ValExpr;
3306de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->reg[reg].arg = j;
3307d69222cb20119a410b777665e16873a2391f9344sewardj         break;
33085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      }
3309d69222cb20119a410b777665e16873a2391f9344sewardj
33105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      case DW_CFA_def_cfa_expression: {
33115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor expr;
33125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         len = step_leb128( &instr, 0 );
33135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         expr = instr;
33145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         instr = ML_(cur_plus)(instr, len);
3315b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
33167888e2204fff6e7429236b4227ed16594e7743b9sewardj            VG_(printf)("  DW_CFA_def_cfa_expression (");
33177888e2204fff6e7429236b4227ed16594e7743b9sewardj         /* Convert the expression into a dag rooted at ctx->exprs index j,
33187888e2204fff6e7429236b4227ed16594e7743b9sewardj            or fail. */
33195690824568ed50e767ad4af4fd10313134141a39sewardj         j = dwarfexpr_to_dag ( ctx, expr, len, False/*!push CFA at start*/,
3320b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                                di->ddump_frames);
3321b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
33227888e2204fff6e7429236b4227ed16594e7743b9sewardj            VG_(printf)(")\n");
3323de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_is_regoff = False;
3324de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_reg       = 0;
3325de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_off       = 0;
3326de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctxs->cfa_expr_ix   = j;
33271e601fe35a89c584cb028b92b000a89d573181c8sewardj         break;
33285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      }
33291e601fe35a89c584cb028b92b000a89d573181c8sewardj
33300cd717757871b2bb53228dae66a28d2b88f18e36sewardj      case DW_CFA_GNU_window_save:
33310cd717757871b2bb53228dae66a28d2b88f18e36sewardj         /* Ignored.  This appears to be sparc-specific; quite why it
33320cd717757871b2bb53228dae66a28d2b88f18e36sewardj            turns up in SuSE-supplied x86 .so's beats me. */
3333b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
33343d026b18e0b41e5f13336f1997054f56cbd89da0sewardj            VG_(printf)("  DW_CFA_GNU_window_save\n");
33353d026b18e0b41e5f13336f1997054f56cbd89da0sewardj         break;
33363d026b18e0b41e5f13336f1997054f56cbd89da0sewardj
33373d026b18e0b41e5f13336f1997054f56cbd89da0sewardj      case DW_CFA_remember_state:
33383d026b18e0b41e5f13336f1997054f56cbd89da0sewardj         if (di->ddump_frames)
33393d026b18e0b41e5f13336f1997054f56cbd89da0sewardj            VG_(printf)("  DW_CFA_remember_state\n");
33403d026b18e0b41e5f13336f1997054f56cbd89da0sewardj         /* we just checked this at entry, so: */
3341de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         vg_assert(ctx->state_sp >= 0 && ctx->state_sp < N_RR_STACK);
3342de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         ctx->state_sp++;
3343de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         if (ctx->state_sp == N_RR_STACK) {
33443d026b18e0b41e5f13336f1997054f56cbd89da0sewardj            /* stack overflow.  We're hosed. */
33453d026b18e0b41e5f13336f1997054f56cbd89da0sewardj            VG_(message)(Vg_DebugMsg, "DWARF2 CFI reader: N_RR_STACK is "
33463d026b18e0b41e5f13336f1997054f56cbd89da0sewardj                                      "too low; increase and recompile.");
33475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            return 0; /* indicate failure */
33483d026b18e0b41e5f13336f1997054f56cbd89da0sewardj         } else {
3349de1b03da8168ecaa16d0fa05f83066f334c6948esewardj            VG_(memcpy)(/*dst*/&ctx->state[ctx->state_sp],
3350de1b03da8168ecaa16d0fa05f83066f334c6948esewardj                        /*src*/&ctx->state[ctx->state_sp - 1],
3351de1b03da8168ecaa16d0fa05f83066f334c6948esewardj                        sizeof(ctx->state[ctx->state_sp]) );
33523d026b18e0b41e5f13336f1997054f56cbd89da0sewardj         }
33533d026b18e0b41e5f13336f1997054f56cbd89da0sewardj         break;
33543d026b18e0b41e5f13336f1997054f56cbd89da0sewardj
33553d026b18e0b41e5f13336f1997054f56cbd89da0sewardj      case DW_CFA_restore_state:
33563d026b18e0b41e5f13336f1997054f56cbd89da0sewardj         if (di->ddump_frames)
33573d026b18e0b41e5f13336f1997054f56cbd89da0sewardj            VG_(printf)("  DW_CFA_restore_state\n");
33583d026b18e0b41e5f13336f1997054f56cbd89da0sewardj         /* we just checked this at entry, so: */
3359de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         vg_assert(ctx->state_sp >= 0 && ctx->state_sp < N_RR_STACK);
3360de1b03da8168ecaa16d0fa05f83066f334c6948esewardj         if (ctx->state_sp == 0) {
33615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            /* stack undefflow.  Give up. */
33625d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            return 0; /* indicate failure */
33633d026b18e0b41e5f13336f1997054f56cbd89da0sewardj         } else {
33643d026b18e0b41e5f13336f1997054f56cbd89da0sewardj            /* simply fall back to previous entry */
3365de1b03da8168ecaa16d0fa05f83066f334c6948esewardj            ctx->state_sp--;
33663d026b18e0b41e5f13336f1997054f56cbd89da0sewardj         }
33670cd717757871b2bb53228dae66a28d2b88f18e36sewardj         break;
33680cd717757871b2bb53228dae66a28d2b88f18e36sewardj
33698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      case DW_CFA_ORCL_arg_loc:
33708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj         if (di->ddump_frames)
33718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj            VG_(printf)("  DW_CFA_ORCL_arg_loc\n");
33728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj         break;
33738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
33745c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      default:
337555022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj         VG_(message)(Vg_DebugMsg, "DWARF2 CFI reader: unhandled CFI "
3376738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                                   "instruction 0:%d\n", (Int)lo6);
3377b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
33783646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  rci:run_CF_instruction:default\n");
33795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         return 0; /* failure */
33805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         /*NOTREACHED*/
33815c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   }
33825c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
33835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return ML_(cur_minus)(instr, instrIN);
33845c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj}
33855c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
33865c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
33873646a495f974e4aacf329e7539a0d584962ff6f6sewardj/* Show a CFI instruction, and also return its length.  Show it as
33883646a495f974e4aacf329e7539a0d584962ff6f6sewardj   close as possible (preferably identical) to how GNU binutils
33893646a495f974e4aacf329e7539a0d584962ff6f6sewardj   readelf --debug-dump=frames would. */
339055022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
33915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic Int show_CF_instruction ( DiCursor instrIN,
3392518850bf0da07ed3e2244e307268ae0fd80e93a8florian                                 const AddressDecodingInfo* adi,
33933646a495f974e4aacf329e7539a0d584962ff6f6sewardj                                 Int code_a_f, Int data_a_f )
33945c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj{
33955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   Int      off, coff, reg, reg2, len;
33965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UInt     delta;
33975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   Addr     loc;
33985d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiCursor instr   = instrIN;
33995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UChar    instr_0 = ML_(cur_step_UChar)(&instr);
34005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UChar    hi2     = (instr_0 >> 6) & 3;
34015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UChar    lo6     = instr_0 & 0x3F;
34025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj
34035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   if (0) {
34045d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiCursor tmpi = instrIN;
34055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      UInt i_0 = ML_(cur_step_UChar)(&tmpi);
34065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      UInt i_1 = ML_(cur_step_UChar)(&tmpi);
34075d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      UInt i_2 = ML_(cur_step_UChar)(&tmpi);
34085d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      UInt i_3 = ML_(cur_step_UChar)(&tmpi);
34095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      UInt i_4 = ML_(cur_step_UChar)(&tmpi);
34105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      UInt i_5 = ML_(cur_step_UChar)(&tmpi);
34115d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      UInt i_6 = ML_(cur_step_UChar)(&tmpi);
34125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      UInt i_7 = ML_(cur_step_UChar)(&tmpi);
34135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      VG_(printf)("raw:%x/%x:%x:%x:%x:%x:%x:%x:%x:%x\n",
34145d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  hi2, lo6, i_0, i_1, i_2, i_3, i_4, i_5, i_6, i_7);
34155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   }
34162fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
34175c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   if (hi2 == DW_CFA_advance_loc) {
34183646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)("  sci:DW_CFA_advance_loc(%d)\n", (Int)lo6);
34195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      return ML_(cur_minus)(instr, instrIN);
34205c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   }
34215c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
34225c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   if (hi2 == DW_CFA_offset) {
34235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      off = step_leb128( &instr, 0 );
34243646a495f974e4aacf329e7539a0d584962ff6f6sewardj      coff = off * data_a_f;
34253646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)("  DW_CFA_offset: r%d at cfa%s%d\n",
34263646a495f974e4aacf329e7539a0d584962ff6f6sewardj                  (Int)lo6, coff < 0 ? "" : "+", (Int)coff );
34275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      return ML_(cur_minus)(instr, instrIN);
34285c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   }
34295c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
34305c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   if (hi2 == DW_CFA_restore) {
34313646a495f974e4aacf329e7539a0d584962ff6f6sewardj      VG_(printf)("  sci:DW_CFA_restore(r%d)\n", (Int)lo6);
34325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      return ML_(cur_minus)(instr, instrIN);
34335c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   }
34345c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
34355c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   vg_assert(hi2 == DW_CFA_use_secondary);
34365c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
34375c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   switch (lo6) {
34385c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
34395c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      case DW_CFA_nop:
34403646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  DW_CFA_nop\n");
34415c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         break;
34425c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
34432fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_CFA_set_loc:
3444ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj         /* WAS: loc = read_Addr(&instr[i]); i+= sizeof(Addr);
3445ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj            (now known to be incorrect -- the address is encoded) */
34465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         loc = step_encoded_Addr(adi, &instr);
3447a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart         VG_(printf)("  sci:DW_CFA_set_loc(%#lx)\n", loc);
34482fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         break;
34492fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
34505c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      case DW_CFA_advance_loc1:
34515d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         delta = (UInt)ML_(cur_step_UChar)(&instr);
3452c6e5d76e9eea8625f385ff844545c688c91938daflorian         VG_(printf)("  sci:DW_CFA_advance_loc1(%u)\n", delta);
34535c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         break;
34545c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
34552fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_CFA_advance_loc2:
34565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         delta = (UInt)ML_(cur_step_UShort)(&instr);
3457c6e5d76e9eea8625f385ff844545c688c91938daflorian         VG_(printf)("  sci:DW_CFA_advance_loc2(%u)\n", delta);
34582fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         break;
34592fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
34602fd38908d48d2a081e59ae67ffdb76b7f611ee8etom      case DW_CFA_advance_loc4:
34615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         delta = (UInt)ML_(cur_step_UInt)(&instr);
3462c6e5d76e9eea8625f385ff844545c688c91938daflorian         VG_(printf)("  DW_CFA_advance_loc4(%u)\n", delta);
34632fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         break;
34642fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
34655c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      case DW_CFA_def_cfa:
34665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0 );
34675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         off = step_leb128( &instr, 0 );
3468c6e5d76e9eea8625f385ff844545c688c91938daflorian         VG_(printf)("  DW_CFA_def_cfa: r%d ofs %d\n", reg, off);
34695c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         break;
34705c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
3471d69222cb20119a410b777665e16873a2391f9344sewardj      case DW_CFA_def_cfa_sf:
34725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0 );
34735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         off = step_leb128( &instr, 1 );
34748c90d27dc7e301e79bc008d1941bd0bc0dc8f362sewardj         VG_(printf)("  DW_CFA_def_cfa_sf: r%d ofs %d\n",
3475c6e5d76e9eea8625f385ff844545c688c91938daflorian                     reg, off * data_a_f);
3476d69222cb20119a410b777665e16873a2391f9344sewardj         break;
3477d69222cb20119a410b777665e16873a2391f9344sewardj
3478e0707a69816ce68deed8de3c7edd940cb4750662sewardj      case DW_CFA_register:
34795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg  = step_leb128( &instr, 0);
34805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg2 = step_leb128( &instr, 0);
34813646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  sci:DW_CFA_register(r%d, r%d)\n", reg, reg2);
3482e0707a69816ce68deed8de3c7edd940cb4750662sewardj         break;
3483e0707a69816ce68deed8de3c7edd940cb4750662sewardj
34845c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      case DW_CFA_def_cfa_register:
34855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0);
34863646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  sci:DW_CFA_def_cfa_register(r%d)\n", reg);
34875c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         break;
34885c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
34895c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      case DW_CFA_def_cfa_offset:
34905d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         off = step_leb128( &instr, 0);
34913646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  sci:DW_CFA_def_cfa_offset(%d)\n", off);
34925c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         break;
34935c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
3494d69222cb20119a410b777665e16873a2391f9344sewardj      case DW_CFA_def_cfa_offset_sf:
34955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         off = step_leb128( &instr, 1);
34963646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  sci:DW_CFA_def_cfa_offset_sf(%d)\n", off);
3497d69222cb20119a410b777665e16873a2391f9344sewardj         break;
3498d69222cb20119a410b777665e16873a2391f9344sewardj
3499d69222cb20119a410b777665e16873a2391f9344sewardj      case DW_CFA_restore_extended:
35005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0);
35013646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  sci:DW_CFA_restore_extended(r%d)\n", reg);
3502d69222cb20119a410b777665e16873a2391f9344sewardj         break;
3503d69222cb20119a410b777665e16873a2391f9344sewardj
3504d69222cb20119a410b777665e16873a2391f9344sewardj      case DW_CFA_undefined:
35055d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0);
35063646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  sci:DW_CFA_undefined(r%d)\n", reg);
3507d69222cb20119a410b777665e16873a2391f9344sewardj         break;
3508d69222cb20119a410b777665e16873a2391f9344sewardj
3509d69222cb20119a410b777665e16873a2391f9344sewardj      case DW_CFA_same_value:
35105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0);
35113646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  sci:DW_CFA_same_value(r%d)\n", reg);
3512d69222cb20119a410b777665e16873a2391f9344sewardj         break;
3513d69222cb20119a410b777665e16873a2391f9344sewardj
3514d69222cb20119a410b777665e16873a2391f9344sewardj      case DW_CFA_remember_state:
35153646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  sci:DW_CFA_remember_state\n");
3516d69222cb20119a410b777665e16873a2391f9344sewardj         break;
3517d69222cb20119a410b777665e16873a2391f9344sewardj
3518d69222cb20119a410b777665e16873a2391f9344sewardj      case DW_CFA_restore_state:
35193646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  sci:DW_CFA_restore_state\n");
3520d69222cb20119a410b777665e16873a2391f9344sewardj         break;
3521d69222cb20119a410b777665e16873a2391f9344sewardj
35225c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      case DW_CFA_GNU_args_size:
35235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         off = step_leb128( &instr, 0 );
35243646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  sci:DW_CFA_GNU_args_size(%d)\n", off );
35255c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         break;
35265c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
35271e601fe35a89c584cb028b92b000a89d573181c8sewardj      case DW_CFA_def_cfa_expression:
35285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         len = step_leb128( &instr, 0 );
35295d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         instr = ML_(cur_plus)(instr, len);
35303646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  sci:DW_CFA_def_cfa_expression(length %d)\n", len);
35311e601fe35a89c584cb028b92b000a89d573181c8sewardj         break;
35321e601fe35a89c584cb028b92b000a89d573181c8sewardj
35331e601fe35a89c584cb028b92b000a89d573181c8sewardj      case DW_CFA_expression:
35345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0 );
35355d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         len = step_leb128( &instr, 0 );
35365d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         instr = ML_(cur_plus)(instr, len);
35373646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  sci:DW_CFA_expression(r%d, length %d)\n", reg, len);
35381e601fe35a89c584cb028b92b000a89d573181c8sewardj         break;
35391e601fe35a89c584cb028b92b000a89d573181c8sewardj
3540d69222cb20119a410b777665e16873a2391f9344sewardj      case DW_CFA_val_expression:
35415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0 );
35425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         len = step_leb128( &instr, 0 );
35435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         instr = ML_(cur_plus)(instr, len);
35443646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  sci:DW_CFA_val_expression(r%d, length %d)\n", reg, len);
3545d69222cb20119a410b777665e16873a2391f9344sewardj         break;
3546d69222cb20119a410b777665e16873a2391f9344sewardj
3547d69222cb20119a410b777665e16873a2391f9344sewardj      case DW_CFA_offset_extended:
35485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0 );
35495d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         off = step_leb128( &instr, 0 );
35503646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  sci:DW_CFA_offset_extended(r%d, "
35513646a495f974e4aacf329e7539a0d584962ff6f6sewardj                     "off %d x data_af)\n", reg, off);
3552d69222cb20119a410b777665e16873a2391f9344sewardj         break;
3553d69222cb20119a410b777665e16873a2391f9344sewardj
3554ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj      case DW_CFA_offset_extended_sf:
35555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0 );
35565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         off = step_leb128( &instr, 1 );
3557ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj	 coff = (Int)(off * data_a_f);
3558ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj         VG_(printf)("  DW_CFA_offset_extended_sf: r%d at cfa%s%d\n",
3559ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj                        reg, coff < 0 ? "" : "+", coff);
3560d69222cb20119a410b777665e16873a2391f9344sewardj         break;
3561d69222cb20119a410b777665e16873a2391f9344sewardj
3562d69222cb20119a410b777665e16873a2391f9344sewardj      case DW_CFA_GNU_negative_offset_extended:
35635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0 );
35645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         off = step_leb128( &instr, 0 );
35653646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  sci:DW_CFA_GNU_negative_offset_extended"
35663646a495f974e4aacf329e7539a0d584962ff6f6sewardj                     "(r%d, off %d x data_af)\n", reg, -off);
3567d69222cb20119a410b777665e16873a2391f9344sewardj         break;
3568d69222cb20119a410b777665e16873a2391f9344sewardj
3569d69222cb20119a410b777665e16873a2391f9344sewardj      case DW_CFA_val_offset:
35705d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0 );
35715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         off = step_leb128( &instr, 0 );
35723646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  sci:DW_CFA_val_offset(r%d, off %d x data_af)\n",
35733646a495f974e4aacf329e7539a0d584962ff6f6sewardj                     reg, off);
3574d69222cb20119a410b777665e16873a2391f9344sewardj         break;
3575d69222cb20119a410b777665e16873a2391f9344sewardj
3576d69222cb20119a410b777665e16873a2391f9344sewardj       case DW_CFA_val_offset_sf:
35775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         reg = step_leb128( &instr, 0 );
35785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         off = step_leb128( &instr, 1 );
35793646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  sci:DW_CFA_val_offset_sf(r%d, off %d x data_af)\n",
35803646a495f974e4aacf329e7539a0d584962ff6f6sewardj                     reg, off);
3581d69222cb20119a410b777665e16873a2391f9344sewardj         break;
3582d69222cb20119a410b777665e16873a2391f9344sewardj
35830cd717757871b2bb53228dae66a28d2b88f18e36sewardj      case DW_CFA_GNU_window_save:
35843646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  sci:DW_CFA_GNU_window_save\n");
35850cd717757871b2bb53228dae66a28d2b88f18e36sewardj         break;
35860cd717757871b2bb53228dae66a28d2b88f18e36sewardj
35878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj      case DW_CFA_ORCL_arg_loc:
35888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj         /* :TODO: Print all arguments when implemented in libdwarf. */
35898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj         VG_(printf)("  sci:DW_CFA_ORCL_arg_loc\n");
35908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj         break;
35918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj
35925c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      default:
35933646a495f974e4aacf329e7539a0d584962ff6f6sewardj         VG_(printf)("  sci:0:%d\n", (Int)lo6);
35945c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         break;
35955c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   }
35965c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
35975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   return ML_(cur_minus)(instr, instrIN);
35985c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj}
35995c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
36005c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
36013646a495f974e4aacf329e7539a0d584962ff6f6sewardj/* Show the instructions in instrs[0 .. ilen-1]. */
36025d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjstatic void show_CF_instructions ( DiCursor instrs, Int ilen,
3603518850bf0da07ed3e2244e307268ae0fd80e93a8florian                                   const AddressDecodingInfo* adi,
36043646a495f974e4aacf329e7539a0d584962ff6f6sewardj                                   Int code_a_f, Int data_a_f )
36055c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj{
36065c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   Int i = 0;
36075c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   while (True) {
36085c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      if (i >= ilen) break;
36095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      i += show_CF_instruction( ML_(cur_plus)(instrs, i),
36105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                adi, code_a_f, data_a_f );
36115c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   }
36125c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj}
36135c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
36143891dd4124828c451c0e36c89a5c6f0f2ac56f71sewardj
36155c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj/* Run the CF instructions in instrs[0 .. ilen-1], until the end is
36165c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   reached, or until there is a failure.  Return True iff success.
36175c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj*/
36185c638c2bda665e232ecf62b5443c93c3d6b7e06asewardjstatic
3619518850bf0da07ed3e2244e307268ae0fd80e93a8florianBool run_CF_instructions ( DebugInfo* di,
36203646a495f974e4aacf329e7539a0d584962ff6f6sewardj                           Bool record,
36215d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                           UnwindContext* ctx, DiCursor instrs, Int ilen,
36228eb413204b3d80f52d207e8292c952f74faa2ca6sewardj                           UWord fde_arange,
3623518850bf0da07ed3e2244e307268ae0fd80e93a8florian                           const UnwindContext* restore_ctx,
3624518850bf0da07ed3e2244e307268ae0fd80e93a8florian                           const AddressDecodingInfo* adi )
36255c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj{
36265c3dba227192de63d86f65ec7d9597c132818c37philippe   Addr base;
36275c3dba227192de63d86f65ec7d9597c132818c37philippe   UInt len;
36285c3dba227192de63d86f65ec7d9597c132818c37philippe   DiCfSI_m cfsi_m;
36293a7cb9777175161f2fd8c8abdea320144721f9d5sewardj   Bool summ_ok;
36305c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   Int j, i = 0;
363135165537cfa2da18220e55e23f21228c1e2591fesewardj   Addr loc_prev;
363235165537cfa2da18220e55e23f21228c1e2591fesewardj   if (0) ppUnwindContext(ctx);
36332fd38908d48d2a081e59ae67ffdb76b7f611ee8etom   if (0) ppUnwindContext_summary(ctx);
36345c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   while (True) {
363535165537cfa2da18220e55e23f21228c1e2591fesewardj      loc_prev = ctx->loc;
36365c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      if (i >= ilen) break;
36375d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      if (0) (void)show_CF_instruction( ML_(cur_plus)(instrs,i), adi,
36383646a495f974e4aacf329e7539a0d584962ff6f6sewardj                                        ctx->code_a_f, ctx->data_a_f );
36395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      j = run_CF_instruction( ctx, ML_(cur_plus)(instrs,i),
36405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                              restore_ctx, adi, di );
36415c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      if (j == 0)
36425c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         return False; /* execution failed */
36435c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      i += j;
364435165537cfa2da18220e55e23f21228c1e2591fesewardj      if (0) ppUnwindContext(ctx);
36453646a495f974e4aacf329e7539a0d584962ff6f6sewardj      if (record && loc_prev != ctx->loc) {
36465c3dba227192de63d86f65ec7d9597c132818c37philippe         summ_ok = summarise_context ( &base, &len, &cfsi_m,
36475c3dba227192de63d86f65ec7d9597c132818c37philippe                                       loc_prev, ctx, di );
36483a7cb9777175161f2fd8c8abdea320144721f9d5sewardj         if (summ_ok) {
36495c3dba227192de63d86f65ec7d9597c132818c37philippe            ML_(addDiCfSI)(di, base, len, &cfsi_m);
3650b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (di->trace_cfi)
36515c3dba227192de63d86f65ec7d9597c132818c37philippe               ML_(ppDiCfSI)(di->cfsi_exprs, base, len, &cfsi_m);
36523a7cb9777175161f2fd8c8abdea320144721f9d5sewardj         }
365335165537cfa2da18220e55e23f21228c1e2591fesewardj      }
365435165537cfa2da18220e55e23f21228c1e2591fesewardj   }
365535165537cfa2da18220e55e23f21228c1e2591fesewardj   if (ctx->loc < fde_arange) {
365635165537cfa2da18220e55e23f21228c1e2591fesewardj      loc_prev = ctx->loc;
365735165537cfa2da18220e55e23f21228c1e2591fesewardj      ctx->loc = fde_arange;
36583646a495f974e4aacf329e7539a0d584962ff6f6sewardj      if (record) {
36595c3dba227192de63d86f65ec7d9597c132818c37philippe         summ_ok = summarise_context ( &base, &len, &cfsi_m,
36605c3dba227192de63d86f65ec7d9597c132818c37philippe                                       loc_prev, ctx, di );
36613a7cb9777175161f2fd8c8abdea320144721f9d5sewardj         if (summ_ok) {
36625c3dba227192de63d86f65ec7d9597c132818c37philippe            ML_(addDiCfSI)(di, base, len, &cfsi_m);
3663b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (di->trace_cfi)
36645c3dba227192de63d86f65ec7d9597c132818c37philippe               ML_(ppDiCfSI)(di->cfsi_exprs, base, len, &cfsi_m);
36653a7cb9777175161f2fd8c8abdea320144721f9d5sewardj         }
366635165537cfa2da18220e55e23f21228c1e2591fesewardj      }
36675c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   }
36685c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   return True;
36695c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj}
36705c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
36715c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
367255022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj/* ------------ Main entry point for CFI reading ------------ */
367355022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj
3674726baecdd1d6614ef65a8d84217cfccde951be66sewardjtypedef
3675726baecdd1d6614ef65a8d84217cfccde951be66sewardj   struct {
3676726baecdd1d6614ef65a8d84217cfccde951be66sewardj      /* This gives the CIE an identity to which FDEs will refer. */
36775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      ULong    offset;
3678726baecdd1d6614ef65a8d84217cfccde951be66sewardj      /* Code, data factors. */
36795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      Int      code_a_f;
36805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      Int      data_a_f;
3681726baecdd1d6614ef65a8d84217cfccde951be66sewardj      /* Return-address pseudo-register. */
36825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      Int      ra_reg;
36835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      UChar    address_encoding;
36845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      /* Where are the instrs? */
36855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiCursor instrs;
36865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      Int      ilen;
3687726baecdd1d6614ef65a8d84217cfccde951be66sewardj      /* God knows .. don't ask */
36885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      Bool     saw_z_augmentation;
3689726baecdd1d6614ef65a8d84217cfccde951be66sewardj   }
3690726baecdd1d6614ef65a8d84217cfccde951be66sewardj   CIE;
3691726baecdd1d6614ef65a8d84217cfccde951be66sewardj
3692726baecdd1d6614ef65a8d84217cfccde951be66sewardjstatic void init_CIE ( CIE* cie )
3693726baecdd1d6614ef65a8d84217cfccde951be66sewardj{
3694726baecdd1d6614ef65a8d84217cfccde951be66sewardj   cie->offset             = 0;
3695726baecdd1d6614ef65a8d84217cfccde951be66sewardj   cie->code_a_f           = 0;
3696726baecdd1d6614ef65a8d84217cfccde951be66sewardj   cie->data_a_f           = 0;
3697726baecdd1d6614ef65a8d84217cfccde951be66sewardj   cie->ra_reg             = 0;
3698726baecdd1d6614ef65a8d84217cfccde951be66sewardj   cie->address_encoding   = 0;
36995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   cie->instrs             = DiCursor_INVALID;
3700726baecdd1d6614ef65a8d84217cfccde951be66sewardj   cie->ilen               = 0;
3701726baecdd1d6614ef65a8d84217cfccde951be66sewardj   cie->saw_z_augmentation = False;
3702726baecdd1d6614ef65a8d84217cfccde951be66sewardj}
3703726baecdd1d6614ef65a8d84217cfccde951be66sewardj
37045f9db7f60ecfb14dfef483a8f8cf91473c7e3b06florianstatic CIE *the_CIEs = NULL;
37055f9db7f60ecfb14dfef483a8f8cf91473c7e3b06florianstatic SizeT N_CIEs = 0;
3706726baecdd1d6614ef65a8d84217cfccde951be66sewardj
3707452e89a9f847975609b3ad318943830f2cce841csewardj/* Read, summarise and store CFA unwind info from .eh_frame and
3708452e89a9f847975609b3ad318943830f2cce841csewardj   .debug_frame sections.  is_ehframe tells us which kind we are
3709452e89a9f847975609b3ad318943830f2cce841csewardj   dealing with -- they are slightly different. */
3710461d6c69908dade34a67afe34b09f54cce74d5a3sewardjvoid ML_(read_callframe_info_dwarf3)
3711452e89a9f847975609b3ad318943830f2cce841csewardj        ( /*OUT*/struct _DebugInfo* di,
37125d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj          DiSlice escn_frame, Addr frame_avma, Bool is_ehframe )
37135c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj{
37146bd9dc18c043927c1196caba20a327238a179c42florian   const HChar* how = NULL;
37155d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   Int      n_CIEs = 0;
37165d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiCursor frame_image = ML_(cur_from_sli)(escn_frame); /* fixed */
37175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiOffT   frame_size  = escn_frame.szB;
37185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   DiCursor data        = frame_image;
37195d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj   UWord    cfsi_used_orig;
3720452e89a9f847975609b3ad318943830f2cce841csewardj
3721452e89a9f847975609b3ad318943830f2cce841csewardj   /* If we're dealing with a .debug_frame, assume zero frame_avma. */
3722452e89a9f847975609b3ad318943830f2cce841csewardj   if (!is_ehframe)
3723452e89a9f847975609b3ad318943830f2cce841csewardj      vg_assert(frame_avma == 0);
37245c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
3725cae0cc22b83ffb260ee8379e92099c5a701944cbcarll#  if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
3726cae0cc22b83ffb260ee8379e92099c5a701944cbcarll      || defined(VGP_ppc64le_linux)
37273c9cf3442185b5891e15450d6e3058aeff6796fetom   /* These targets don't use CFI-based stack unwinding.  */
372885665ca6fa29dd64754dabe50eb98f25896e752acerion   return;
37291936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj#  endif
373085665ca6fa29dd64754dabe50eb98f25896e752acerion
3731452e89a9f847975609b3ad318943830f2cce841csewardj   /* If we read more than one .debug_frame or .eh_frame for this
3732452e89a9f847975609b3ad318943830f2cce841csewardj      DebugInfo*, the second and subsequent reads should only add FDEs
3733452e89a9f847975609b3ad318943830f2cce841csewardj      for address ranges not already covered by the FDEs already
3734452e89a9f847975609b3ad318943830f2cce841csewardj      present.  To be able to quickly check which address ranges are
3735452e89a9f847975609b3ad318943830f2cce841csewardj      already present, any existing records (DiCFSIs) must be sorted,
3736452e89a9f847975609b3ad318943830f2cce841csewardj      so we can binary-search them in the code below.  We also record
3737452e89a9f847975609b3ad318943830f2cce841csewardj      di->cfsi_used so that we know where the boundary is between
3738452e89a9f847975609b3ad318943830f2cce841csewardj      existing and new records. */
3739452e89a9f847975609b3ad318943830f2cce841csewardj   if (di->cfsi_used > 0) {
37403c9cf3442185b5891e15450d6e3058aeff6796fetom      ML_(canonicaliseCFI) ( di );
37413c9cf3442185b5891e15450d6e3058aeff6796fetom   }
3742452e89a9f847975609b3ad318943830f2cce841csewardj   cfsi_used_orig = di->cfsi_used;
37433c9cf3442185b5891e15450d6e3058aeff6796fetom
3744b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj   if (di->trace_cfi) {
3745325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj      VG_(printf)("\n-----------------------------------------------\n");
3746c6e5d76e9eea8625f385ff844545c688c91938daflorian      VG_(printf)("CFI info: szB %llu, _avma %#lx\n",
37475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  escn_frame.szB, frame_avma );
37485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      VG_(printf)("CFI info: name %s\n", di->fsm.filename );
3749325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj   }
3750325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj
37515c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   /* Loop over CIEs/FDEs */
37525c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
3753726baecdd1d6614ef65a8d84217cfccde951be66sewardj   /* Conceptually, the frame info is a sequence of FDEs, one for each
3754726baecdd1d6614ef65a8d84217cfccde951be66sewardj      function.  Inside an FDE is a miniature program for a special
3755726baecdd1d6614ef65a8d84217cfccde951be66sewardj      state machine, which, when run, produces the stack-unwinding
3756726baecdd1d6614ef65a8d84217cfccde951be66sewardj      info for that function.
3757726baecdd1d6614ef65a8d84217cfccde951be66sewardj
3758726baecdd1d6614ef65a8d84217cfccde951be66sewardj      Because the FDEs typically have much in common, and because the
3759726baecdd1d6614ef65a8d84217cfccde951be66sewardj      DWARF designers appear to have been fanatical about space
3760726baecdd1d6614ef65a8d84217cfccde951be66sewardj      saving, the common parts are factored out into so-called CIEs.
3761726baecdd1d6614ef65a8d84217cfccde951be66sewardj      That means that what we traverse is a sequence of structs, each
3762726baecdd1d6614ef65a8d84217cfccde951be66sewardj      of which is either a FDE (usually) or a CIE (occasionally).
3763726baecdd1d6614ef65a8d84217cfccde951be66sewardj      Each FDE has a field indicating which CIE is the one pertaining
3764726baecdd1d6614ef65a8d84217cfccde951be66sewardj      to it.
3765726baecdd1d6614ef65a8d84217cfccde951be66sewardj
3766726baecdd1d6614ef65a8d84217cfccde951be66sewardj      The following loop traverses the sequence.  FDEs are dealt with
3767726baecdd1d6614ef65a8d84217cfccde951be66sewardj      immediately; once we harvest the useful info in an FDE, it is
3768726baecdd1d6614ef65a8d84217cfccde951be66sewardj      then forgotten about.  By contrast, CIEs are validated and
3769726baecdd1d6614ef65a8d84217cfccde951be66sewardj      dumped into an array, because later FDEs may refer to any
3770726baecdd1d6614ef65a8d84217cfccde951be66sewardj      previously-seen CIE.
3771726baecdd1d6614ef65a8d84217cfccde951be66sewardj   */
37725c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   while (True) {
37735d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      DiCursor ciefde_start;
37745d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      ULong    ciefde_len;
37755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      ULong    cie_pointer;
37765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      Bool     dw64;
37775c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
3778325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj      /* Are we done? */
37795d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      if (ML_(cur_cmpEQ)(data, ML_(cur_plus)(frame_image, frame_size)))
3780325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj         return;
37815c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
3782325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj      /* Overshot the end?  Means something is wrong */
37835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      if (ML_(cur_cmpGT)(data, ML_(cur_plus)(frame_image, frame_size))) {
3784325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj         how = "overran the end of .eh_frame";
3785325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj         goto bad;
3786325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj      }
37875c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
3788325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj      /* Ok, we must be looking at the start of a new CIE or FDE.
3789325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj         Figure out which it is. */
37905c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
379160a4b0b77180f0c54ddca5c8d9ca20a877637f01tom      ciefde_start = data;
3792b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (di->trace_cfi)
37935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         VG_(printf)("\ncie/fde.start   = (frame_image + 0x%llx)\n",
3794c6e5d76e9eea8625f385ff844545c688c91938daflorian                     (ULong)ML_(cur_minus)(ciefde_start, frame_image));
37955c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
37965d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj      ciefde_len = (ULong)ML_(cur_step_UInt)(&data);
3797b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (di->trace_cfi)
3798c6e5d76e9eea8625f385ff844545c688c91938daflorian         VG_(printf)("cie/fde.length  = %llu\n", ciefde_len);
37995c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
38005c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      /* Apparently, if the .length field is zero, we are at the end
3801461d6c69908dade34a67afe34b09f54cce74d5a3sewardj         of the sequence.  This is stated in the Generic Elf
3802461d6c69908dade34a67afe34b09f54cce74d5a3sewardj         Specification (see comments far above here) and is one of the
3803461d6c69908dade34a67afe34b09f54cce74d5a3sewardj         places where .eh_frame and .debug_frame data differ. */
38045c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      if (ciefde_len == 0) {
3805b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
38065d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            VG_(printf)("%08llx ZERO terminator\n\n",
3807c6e5d76e9eea8625f385ff844545c688c91938daflorian                        (ULong)ML_(cur_minus)(ciefde_start, frame_image));
3808461d6c69908dade34a67afe34b09f54cce74d5a3sewardj         return;
3809461d6c69908dade34a67afe34b09f54cce74d5a3sewardj      }
3810461d6c69908dade34a67afe34b09f54cce74d5a3sewardj
3811461d6c69908dade34a67afe34b09f54cce74d5a3sewardj      /* If the .length field is 0xFFFFFFFF then we're dealing with
3812461d6c69908dade34a67afe34b09f54cce74d5a3sewardj         64-bit DWARF, and the real length is stored as a 64-bit
3813461d6c69908dade34a67afe34b09f54cce74d5a3sewardj         number immediately following it. */
3814461d6c69908dade34a67afe34b09f54cce74d5a3sewardj      dw64 = False;
3815461d6c69908dade34a67afe34b09f54cce74d5a3sewardj      if (ciefde_len == 0xFFFFFFFFUL) {
3816461d6c69908dade34a67afe34b09f54cce74d5a3sewardj         dw64 = True;
38175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ciefde_len = ML_(cur_step_ULong)(&data);
3818461d6c69908dade34a67afe34b09f54cce74d5a3sewardj      }
3819461d6c69908dade34a67afe34b09f54cce74d5a3sewardj
3820461d6c69908dade34a67afe34b09f54cce74d5a3sewardj      /* Now get the CIE ID, whose size depends on the DWARF 32 vs
3821461d6c69908dade34a67afe34b09f54cce74d5a3sewardj	 64-ness. */
3822461d6c69908dade34a67afe34b09f54cce74d5a3sewardj      if (dw64) {
38235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         /* see XXX below */
38245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cie_pointer = ML_(cur_step_ULong)(&data);
3825461d6c69908dade34a67afe34b09f54cce74d5a3sewardj      } else {
38265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         /* see XXX below */
38275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cie_pointer = (ULong)ML_(cur_step_UInt)(&data);
38285c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      }
38295c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
3830b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj      if (di->trace_cfi)
3831c6e5d76e9eea8625f385ff844545c688c91938daflorian         VG_(printf)("cie.pointer     = %llu\n", cie_pointer);
38325c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
38333c9cf3442185b5891e15450d6e3058aeff6796fetom      /* If cie_pointer is zero for .eh_frame or all ones for .debug_frame,
38343c9cf3442185b5891e15450d6e3058aeff6796fetom         we've got a CIE; else it's an FDE. */
3835452e89a9f847975609b3ad318943830f2cce841csewardj      if (cie_pointer == (is_ehframe ? 0ULL
38363c9cf3442185b5891e15450d6e3058aeff6796fetom                          : dw64 ? 0xFFFFFFFFFFFFFFFFULL : 0xFFFFFFFFULL)) {
38375c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
38385d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         Int      this_CIE;
38395d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UChar    cie_version;
38405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor cie_augmentation;
38415c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
38425c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         /* --------- CIE --------- */
3843b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	 if (di->trace_cfi)
38445f9db7f60ecfb14dfef483a8f8cf91473c7e3b06florian            VG_(printf)("------ new CIE #%d ------\n", n_CIEs);
3845726baecdd1d6614ef65a8d84217cfccde951be66sewardj
3846726baecdd1d6614ef65a8d84217cfccde951be66sewardj	 /* Allocate a new CIE record. */
38475f9db7f60ecfb14dfef483a8f8cf91473c7e3b06florian         vg_assert(n_CIEs >= 0);
3848726baecdd1d6614ef65a8d84217cfccde951be66sewardj         if (n_CIEs == N_CIEs) {
38495f9db7f60ecfb14dfef483a8f8cf91473c7e3b06florian            N_CIEs += 1000;
38505f9db7f60ecfb14dfef483a8f8cf91473c7e3b06florian            the_CIEs = ML_(dinfo_realloc)("di.rcid3.2", the_CIEs,
38515f9db7f60ecfb14dfef483a8f8cf91473c7e3b06florian                                          N_CIEs * sizeof the_CIEs[0]);
3852726baecdd1d6614ef65a8d84217cfccde951be66sewardj         }
3853726baecdd1d6614ef65a8d84217cfccde951be66sewardj
3854726baecdd1d6614ef65a8d84217cfccde951be66sewardj         this_CIE = n_CIEs;
3855726baecdd1d6614ef65a8d84217cfccde951be66sewardj         n_CIEs++;
3856726baecdd1d6614ef65a8d84217cfccde951be66sewardj         init_CIE( &the_CIEs[this_CIE] );
3857726baecdd1d6614ef65a8d84217cfccde951be66sewardj
3858726baecdd1d6614ef65a8d84217cfccde951be66sewardj	 /* Record its offset.  This is how we will find it again
3859726baecdd1d6614ef65a8d84217cfccde951be66sewardj            later when looking at an FDE. */
38605d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         the_CIEs[this_CIE].offset
38615d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            = (ULong)ML_(cur_minus)(ciefde_start, frame_image);
3862325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj
3863b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
38643646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("%08lx %08lx %08lx CIE\n",
38655d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                        (Addr)ML_(cur_minus)(ciefde_start, frame_image),
38663646a495f974e4aacf329e7539a0d584962ff6f6sewardj                        (Addr)ciefde_len,
3867461d6c69908dade34a67afe34b09f54cce74d5a3sewardj                        (Addr)(UWord)cie_pointer );
38683646a495f974e4aacf329e7539a0d584962ff6f6sewardj
38695d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         cie_version = ML_(cur_step_UChar)(&data);
3870b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->trace_cfi)
3871325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj            VG_(printf)("cie.version     = %d\n", (Int)cie_version);
3872b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
38733646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  Version:               %d\n", (Int)cie_version);
3874fba428cd266b8a39db641c5fd9523daa8939bed0tom         if (cie_version != 1 && cie_version != 3 && cie_version != 4) {
3875fba428cd266b8a39db641c5fd9523daa8939bed0tom            how = "unexpected CIE version (not 1 nor 3 nor 4)";
3876325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj            goto bad;
3877325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj         }
38785c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
387960a4b0b77180f0c54ddca5c8d9ca20a877637f01tom         cie_augmentation = data;
38805d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         data = ML_(cur_plus)(data, 1 + ML_(cur_strlen)(cie_augmentation));
38815c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
38825d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (di->trace_cfi || di->ddump_frames) {
38835d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            HChar* str = ML_(cur_read_strdup)(cie_augmentation, "di.rcid3.1");
38845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            if (di->trace_cfi)
38855d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               VG_(printf)("cie.augment     = \"%s\"\n", str);
38865d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            if (di->ddump_frames)
38875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj               VG_(printf)("  Augmentation:          \"%s\"\n", str);
38885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            ML_(dinfo_free)(str);
38895d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         }
38905c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
38915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         if (ML_(cur_read_UChar)(cie_augmentation) == 'e'
38925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj             && ML_(cur_read_UChar)
38935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                   (ML_(cur_plus)(cie_augmentation, 1)) == 'h') {
38945d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            data = ML_(cur_plus)(data, sizeof(Addr));
38955d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            cie_augmentation = ML_(cur_plus)(cie_augmentation, 2);
38965c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         }
38975c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
3898fba428cd266b8a39db641c5fd9523daa8939bed0tom         if (cie_version >= 4) {
38995d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            if (ML_(cur_step_UChar)(&data) != sizeof(Addr)) {
3900fba428cd266b8a39db641c5fd9523daa8939bed0tom               how = "unexpected address size";
3901fba428cd266b8a39db641c5fd9523daa8939bed0tom               goto bad;
3902fba428cd266b8a39db641c5fd9523daa8939bed0tom            }
39035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            if (ML_(cur_step_UChar)(&data) != 0) {
3904fba428cd266b8a39db641c5fd9523daa8939bed0tom               how = "unexpected non-zero segment size";
3905fba428cd266b8a39db641c5fd9523daa8939bed0tom               goto bad;
3906fba428cd266b8a39db641c5fd9523daa8939bed0tom            }
3907fba428cd266b8a39db641c5fd9523daa8939bed0tom         }
3908fba428cd266b8a39db641c5fd9523daa8939bed0tom
39095d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         the_CIEs[this_CIE].code_a_f = step_leb128( &data, 0);
3910b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->trace_cfi)
3911726baecdd1d6614ef65a8d84217cfccde951be66sewardj            VG_(printf)("cie.code_af     = %d\n",
3912726baecdd1d6614ef65a8d84217cfccde951be66sewardj                        the_CIEs[this_CIE].code_a_f);
3913b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
39143646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  Code alignment factor: %d\n",
39153646a495f974e4aacf329e7539a0d584962ff6f6sewardj                        (Int)the_CIEs[this_CIE].code_a_f);
39165c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
39175d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         the_CIEs[this_CIE].data_a_f = step_leb128( &data, 1);
3918b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->trace_cfi)
3919726baecdd1d6614ef65a8d84217cfccde951be66sewardj            VG_(printf)("cie.data_af     = %d\n",
3920726baecdd1d6614ef65a8d84217cfccde951be66sewardj                        the_CIEs[this_CIE].data_a_f);
3921b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
39223646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  Data alignment factor: %d\n",
39233646a495f974e4aacf329e7539a0d584962ff6f6sewardj                        (Int)the_CIEs[this_CIE].data_a_f);
39245c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
39253c9cf3442185b5891e15450d6e3058aeff6796fetom         if (cie_version == 1) {
39265d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            the_CIEs[this_CIE].ra_reg = (Int)ML_(cur_step_UChar)(&data);
39273c9cf3442185b5891e15450d6e3058aeff6796fetom         } else {
39285d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            the_CIEs[this_CIE].ra_reg = step_leb128( &data, 0);
39293c9cf3442185b5891e15450d6e3058aeff6796fetom         }
3930b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->trace_cfi)
3931726baecdd1d6614ef65a8d84217cfccde951be66sewardj            VG_(printf)("cie.ra_reg      = %d\n",
3932726baecdd1d6614ef65a8d84217cfccde951be66sewardj                        the_CIEs[this_CIE].ra_reg);
3933b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
39343646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("  Return address column: %d\n",
39353646a495f974e4aacf329e7539a0d584962ff6f6sewardj                        (Int)the_CIEs[this_CIE].ra_reg);
39363646a495f974e4aacf329e7539a0d584962ff6f6sewardj
3937726baecdd1d6614ef65a8d84217cfccde951be66sewardj         if (the_CIEs[this_CIE].ra_reg < 0
3938726baecdd1d6614ef65a8d84217cfccde951be66sewardj             || the_CIEs[this_CIE].ra_reg >= N_CFI_REGS) {
39395410cfd1cc18617076b8c7f41d837bdc90117d38sewardj            how = "cie.ra_reg has implausible value";
394055022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj            goto bad;
394155022aa08ccb267fe73f31f73c6f6f0f0e7198b2sewardj         }
39425c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
3943726baecdd1d6614ef65a8d84217cfccde951be66sewardj         the_CIEs[this_CIE].saw_z_augmentation
39445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            = ML_(cur_read_UChar)(cie_augmentation) == 'z';
3945726baecdd1d6614ef65a8d84217cfccde951be66sewardj         if (the_CIEs[this_CIE].saw_z_augmentation) {
39465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            UInt length = step_leb128( &data, 0);
39475d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            the_CIEs[this_CIE].instrs = ML_(cur_plus)(data, length);
39485d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            cie_augmentation = ML_(cur_plus)(cie_augmentation, 1);
3949b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (di->ddump_frames) {
39503646a495f974e4aacf329e7539a0d584962ff6f6sewardj               UInt i;
3951687bbf6d72a26d7f7f35f672a67ca2bbe1455a8dsewardj               VG_(printf)("  Augmentation data:    ");
39523646a495f974e4aacf329e7539a0d584962ff6f6sewardj               for (i = 0; i < length; i++)
39535d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  VG_(printf)(" %02x", (UInt)ML_(cur_read_UChar)
39545d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                                (ML_(cur_plus)(data, i)));
39553646a495f974e4aacf329e7539a0d584962ff6f6sewardj               VG_(printf)("\n");
39563646a495f974e4aacf329e7539a0d584962ff6f6sewardj            }
39572fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         } else {
39585d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            the_CIEs[this_CIE].instrs = DiCursor_INVALID;
39592fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         }
39602fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
3961726baecdd1d6614ef65a8d84217cfccde951be66sewardj         the_CIEs[this_CIE].address_encoding = default_Addr_encoding();
3962f04fd62c466fe6868a67bbc6daa64db6fdd29f38tom
39635d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         while (ML_(cur_read_UChar)(cie_augmentation)) {
39645d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            switch (ML_(cur_read_UChar)(cie_augmentation)) {
39652fd38908d48d2a081e59ae67ffdb76b7f611ee8etom               case 'L':
39665d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  data = ML_(cur_plus)(data, 1);
39675d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  cie_augmentation = ML_(cur_plus)(cie_augmentation, 1);
39682fd38908d48d2a081e59ae67ffdb76b7f611ee8etom                  break;
39692fd38908d48d2a081e59ae67ffdb76b7f611ee8etom               case 'R':
3970726baecdd1d6614ef65a8d84217cfccde951be66sewardj                  the_CIEs[this_CIE].address_encoding
39715d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                     = ML_(cur_step_UChar)(&data);
39725d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  cie_augmentation = ML_(cur_plus)(cie_augmentation, 1);
39732fd38908d48d2a081e59ae67ffdb76b7f611ee8etom                  break;
39742fd38908d48d2a081e59ae67ffdb76b7f611ee8etom               case 'P':
39755d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  data = ML_(cur_plus)(data, size_of_encoded_Addr(
39765d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                                ML_(cur_read_UChar)(data) ));
39775d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  data = ML_(cur_plus)(data, 1);
39785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  cie_augmentation = ML_(cur_plus)(cie_augmentation, 1);
39792fd38908d48d2a081e59ae67ffdb76b7f611ee8etom                  break;
3980d69222cb20119a410b777665e16873a2391f9344sewardj               case 'S':
39815d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  cie_augmentation = ML_(cur_plus)(cie_augmentation, 1);
3982d69222cb20119a410b777665e16873a2391f9344sewardj                  break;
39832fd38908d48d2a081e59ae67ffdb76b7f611ee8etom               default:
39845d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  if (!ML_(cur_is_valid)(the_CIEs[this_CIE].instrs)) {
39852fd38908d48d2a081e59ae67ffdb76b7f611ee8etom                     how = "unhandled cie.augmentation";
39862fd38908d48d2a081e59ae67ffdb76b7f611ee8etom                     goto bad;
39872fd38908d48d2a081e59ae67ffdb76b7f611ee8etom                  }
3988726baecdd1d6614ef65a8d84217cfccde951be66sewardj                  data = the_CIEs[this_CIE].instrs;
39892fd38908d48d2a081e59ae67ffdb76b7f611ee8etom                  goto done_augmentation;
39902fd38908d48d2a081e59ae67ffdb76b7f611ee8etom            }
39912fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         }
39922fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
39932fd38908d48d2a081e59ae67ffdb76b7f611ee8etom        done_augmentation:
39942fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
3995b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->trace_cfi)
3996726baecdd1d6614ef65a8d84217cfccde951be66sewardj            VG_(printf)("cie.encoding    = 0x%x\n",
3997726baecdd1d6614ef65a8d84217cfccde951be66sewardj                        the_CIEs[this_CIE].address_encoding);
39982fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
3999726baecdd1d6614ef65a8d84217cfccde951be66sewardj         the_CIEs[this_CIE].instrs = data;
40005d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         the_CIEs[this_CIE].ilen   = ML_(cur_minus)(ciefde_start, data)
40015d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                     + (Long)ciefde_len + (Long)sizeof(UInt);
4002b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->trace_cfi) {
40035d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            //VG_(printf)("cie.instrs      = %p\n", the_CIEs[this_CIE].instrs);
4004726baecdd1d6614ef65a8d84217cfccde951be66sewardj            VG_(printf)("cie.ilen        = %d\n", the_CIEs[this_CIE].ilen);
4005325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj	 }
40065c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
4007726baecdd1d6614ef65a8d84217cfccde951be66sewardj         if (the_CIEs[this_CIE].ilen < 0
40083c9cf3442185b5891e15450d6e3058aeff6796fetom             || the_CIEs[this_CIE].ilen > frame_size) {
40095c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj            how = "implausible # cie initial insns";
40105c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj            goto bad;
40115c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         }
40125c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
40135d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         data = ML_(cur_plus)(data, the_CIEs[this_CIE].ilen);
40145c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
40153646a495f974e4aacf329e7539a0d584962ff6f6sewardj         /* Show the CIE's instructions (the preamble for each FDE
40163646a495f974e4aacf329e7539a0d584962ff6f6sewardj            that uses this CIE). */
4017b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
40183646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("\n");
40193646a495f974e4aacf329e7539a0d584962ff6f6sewardj
4020b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->trace_cfi || di->ddump_frames) {
40211936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj            AddressDecodingInfo adi;
4022c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj            adi.encoding      = the_CIEs[this_CIE].address_encoding;
40233c9cf3442185b5891e15450d6e3058aeff6796fetom            adi.ehframe_image = frame_image;
40243c9cf3442185b5891e15450d6e3058aeff6796fetom            adi.ehframe_avma  = frame_avma;
4025402c9eed11b9b60c6e134d05db938e395466cf99tom            adi.text_bias     = di->text_debug_bias;
40268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj            adi.got_avma      = di->got_avma;
40273646a495f974e4aacf329e7539a0d584962ff6f6sewardj            show_CF_instructions( the_CIEs[this_CIE].instrs,
40283646a495f974e4aacf329e7539a0d584962ff6f6sewardj                                  the_CIEs[this_CIE].ilen, &adi,
40293646a495f974e4aacf329e7539a0d584962ff6f6sewardj                                  the_CIEs[this_CIE].code_a_f,
40303646a495f974e4aacf329e7539a0d584962ff6f6sewardj                                  the_CIEs[this_CIE].data_a_f );
40311936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj         }
40325c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
4033b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
40343646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("\n");
40353646a495f974e4aacf329e7539a0d584962ff6f6sewardj
40365c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      } else {
40375c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
40381936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj         AddressDecodingInfo adi;
4039726baecdd1d6614ef65a8d84217cfccde951be66sewardj         UnwindContext ctx, restore_ctx;
40405d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         Int      cie;
40415d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         ULong    look_for;
40425d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         Bool     ok;
40435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         Addr     fde_initloc;
40445d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         UWord    fde_arange;
40455d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         DiCursor fde_instrs;
40465d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         Int      fde_ilen;
4047726baecdd1d6614ef65a8d84217cfccde951be66sewardj
40485c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         /* --------- FDE --------- */
40495c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
4050726baecdd1d6614ef65a8d84217cfccde951be66sewardj         /* Find the relevant CIE.  The CIE we want is located
4051726baecdd1d6614ef65a8d84217cfccde951be66sewardj            cie_pointer bytes back from here. */
4052726baecdd1d6614ef65a8d84217cfccde951be66sewardj
4053461d6c69908dade34a67afe34b09f54cce74d5a3sewardj         /* re sizeof(UInt) / sizeof(ULong), matches XXX above. */
4054452e89a9f847975609b3ad318943830f2cce841csewardj         if (is_ehframe)
40555d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            look_for = ML_(cur_minus)(data, frame_image)
40565d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                       - (dw64 ? sizeof(ULong) : sizeof(UInt))
40573c9cf3442185b5891e15450d6e3058aeff6796fetom                       - cie_pointer;
40583c9cf3442185b5891e15450d6e3058aeff6796fetom         else
40593c9cf3442185b5891e15450d6e3058aeff6796fetom            look_for = cie_pointer;
4060726baecdd1d6614ef65a8d84217cfccde951be66sewardj
4061726baecdd1d6614ef65a8d84217cfccde951be66sewardj         for (cie = 0; cie < n_CIEs; cie++) {
4062c6e5d76e9eea8625f385ff844545c688c91938daflorian            if (0) VG_(printf)("look for %llu   %llu\n",
4063726baecdd1d6614ef65a8d84217cfccde951be66sewardj                               look_for, the_CIEs[cie].offset );
4064726baecdd1d6614ef65a8d84217cfccde951be66sewardj            if (the_CIEs[cie].offset == look_for)
4065726baecdd1d6614ef65a8d84217cfccde951be66sewardj               break;
4066726baecdd1d6614ef65a8d84217cfccde951be66sewardj	 }
4067726baecdd1d6614ef65a8d84217cfccde951be66sewardj         vg_assert(cie >= 0 && cie <= n_CIEs);
4068726baecdd1d6614ef65a8d84217cfccde951be66sewardj         if (cie == n_CIEs) {
4069726baecdd1d6614ef65a8d84217cfccde951be66sewardj            how = "FDE refers to not-findable CIE";
407035165537cfa2da18220e55e23f21228c1e2591fesewardj            goto bad;
4071726baecdd1d6614ef65a8d84217cfccde951be66sewardj	 }
40725c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
4073c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj         adi.encoding      = the_CIEs[cie].address_encoding;
40743c9cf3442185b5891e15450d6e3058aeff6796fetom         adi.ehframe_image = frame_image;
40753c9cf3442185b5891e15450d6e3058aeff6796fetom         adi.ehframe_avma  = frame_avma;
4076402c9eed11b9b60c6e134d05db938e395466cf99tom         adi.text_bias     = di->text_debug_bias;
40778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj         adi.got_avma      = di->got_avma;
40785d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         fde_initloc = step_encoded_Addr(&adi, &data);
4079b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->trace_cfi)
4080a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart            VG_(printf)("fde.initloc     = %#lx\n", fde_initloc);
40815c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
4082c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj         adi.encoding      = the_CIEs[cie].address_encoding & 0xf;
40833c9cf3442185b5891e15450d6e3058aeff6796fetom         adi.ehframe_image = frame_image;
40843c9cf3442185b5891e15450d6e3058aeff6796fetom         adi.ehframe_avma  = frame_avma;
4085402c9eed11b9b60c6e134d05db938e395466cf99tom         adi.text_bias     = di->text_debug_bias;
40868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj         adi.got_avma      = di->got_avma;
4087ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj
4088ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj         /* WAS (incorrectly):
4089ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj            fde_arange = read_encoded_Addr(&nbytes, &adi, data);
4090ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj            data += nbytes;
4091ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj            The following corresponds to what binutils/dwarf.c does:
4092ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj         */
4093ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj         { UInt ptr_size = size_of_encoded_Addr( adi.encoding );
4094ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj           switch (ptr_size) {
4095ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj              case 8: case 4: case 2: case 1:
4096ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj                 fde_arange
40975d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                    = (UWord)step_le_u_encoded_literal(&data, ptr_size);
4098ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj                 break;
4099ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj              default:
4100ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj                 how = "unknown arange field encoding in FDE";
4101ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj                 goto bad;
4102ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj           }
4103ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj         }
4104ddf006d7198dbfc0b02cd975360722bb0a15dc82sewardj
4105b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->trace_cfi)
4106a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart            VG_(printf)("fde.arangec     = %#lx\n", fde_arange);
41075c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
4108b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->ddump_frames)
41093646a495f974e4aacf329e7539a0d584962ff6f6sewardj            VG_(printf)("%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
41105d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                        (Addr)ML_(cur_minus)(ciefde_start, frame_image),
41113646a495f974e4aacf329e7539a0d584962ff6f6sewardj                        (Addr)ciefde_len,
4112461d6c69908dade34a67afe34b09f54cce74d5a3sewardj                        (Addr)(UWord)cie_pointer,
41133646a495f974e4aacf329e7539a0d584962ff6f6sewardj                        (Addr)look_for,
4114402c9eed11b9b60c6e134d05db938e395466cf99tom                        ((Addr)fde_initloc) - di->text_debug_bias,
4115402c9eed11b9b60c6e134d05db938e395466cf99tom                        ((Addr)fde_initloc) - di->text_debug_bias + fde_arange);
41163646a495f974e4aacf329e7539a0d584962ff6f6sewardj
4117726baecdd1d6614ef65a8d84217cfccde951be66sewardj         if (the_CIEs[cie].saw_z_augmentation) {
41185d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            UInt length = step_leb128( &data, 0);
4119b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (di->ddump_frames && (length > 0)) {
4120687bbf6d72a26d7f7f35f672a67ca2bbe1455a8dsewardj               UInt i;
4121687bbf6d72a26d7f7f35f672a67ca2bbe1455a8dsewardj               VG_(printf)("  Augmentation data:    ");
4122687bbf6d72a26d7f7f35f672a67ca2bbe1455a8dsewardj               for (i = 0; i < length; i++)
41235d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                  VG_(printf)(" %02x", (UInt)ML_(cur_read_UChar)
41245d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                                                (ML_(cur_plus)(data, i)));
4125687bbf6d72a26d7f7f35f672a67ca2bbe1455a8dsewardj               VG_(printf)("\n\n");
4126687bbf6d72a26d7f7f35f672a67ca2bbe1455a8dsewardj            }
41275d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            data = ML_(cur_plus)(data, length);
41282fd38908d48d2a081e59ae67ffdb76b7f611ee8etom         }
41292fd38908d48d2a081e59ae67ffdb76b7f611ee8etom
413060a4b0b77180f0c54ddca5c8d9ca20a877637f01tom         fde_instrs = data;
41315d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj         fde_ilen   = ML_(cur_minus)(ciefde_start, data)
41325d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj                      + (Long)ciefde_len + (Long)sizeof(UInt);
4133b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->trace_cfi) {
41345d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj            //VG_(printf)("fde.instrs      = %p\n", fde_instrs);
41358eb413204b3d80f52d207e8292c952f74faa2ca6sewardj            VG_(printf)("fde.ilen        = %d\n", (Int)fde_ilen);
41368eb413204b3d80f52d207e8292c952f74faa2ca6sewardj	 }
41375c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
41383c9cf3442185b5891e15450d6e3058aeff6796fetom         if (fde_ilen < 0 || fde_ilen > frame_size) {
4139325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj            how = "implausible # fde insns";
41405c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj            goto bad;
41415c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj         }
41425c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
41435d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardj	 data = ML_(cur_plus)(data, fde_ilen);
41445c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
4145452e89a9f847975609b3ad318943830f2cce841csewardj         /* If this object's DebugInfo* had some DiCFSIs from a
4146452e89a9f847975609b3ad318943830f2cce841csewardj            previous .eh_frame or .debug_frame read, we must check
4147452e89a9f847975609b3ad318943830f2cce841csewardj            that we're not adding a duplicate. */
4148452e89a9f847975609b3ad318943830f2cce841csewardj         if (cfsi_used_orig > 0) {
41493c9cf3442185b5891e15450d6e3058aeff6796fetom            Addr a_mid_lo, a_mid_hi;
41503c9cf3442185b5891e15450d6e3058aeff6796fetom            Word mid, size,
41513c9cf3442185b5891e15450d6e3058aeff6796fetom                 lo = 0,
4152452e89a9f847975609b3ad318943830f2cce841csewardj                 hi = cfsi_used_orig-1;
41533c9cf3442185b5891e15450d6e3058aeff6796fetom            while (True) {
41543c9cf3442185b5891e15450d6e3058aeff6796fetom               /* current unsearched space is from lo to hi, inclusive. */
41553c9cf3442185b5891e15450d6e3058aeff6796fetom               if (lo > hi) break; /* not found */
41563c9cf3442185b5891e15450d6e3058aeff6796fetom               mid      = (lo + hi) / 2;
41575c3dba227192de63d86f65ec7d9597c132818c37philippe               a_mid_lo = di->cfsi_rd[mid].base;
41585c3dba227192de63d86f65ec7d9597c132818c37philippe               size     = di->cfsi_rd[mid].len;
41593c9cf3442185b5891e15450d6e3058aeff6796fetom               a_mid_hi = a_mid_lo + size - 1;
41603c9cf3442185b5891e15450d6e3058aeff6796fetom               vg_assert(a_mid_hi >= a_mid_lo);
41613c9cf3442185b5891e15450d6e3058aeff6796fetom               if (fde_initloc + fde_arange <= a_mid_lo) {
41623c9cf3442185b5891e15450d6e3058aeff6796fetom                  hi = mid-1; continue;
41633c9cf3442185b5891e15450d6e3058aeff6796fetom               }
41643c9cf3442185b5891e15450d6e3058aeff6796fetom               if (fde_initloc > a_mid_hi) { lo = mid+1; continue; }
41653c9cf3442185b5891e15450d6e3058aeff6796fetom               break;
41663c9cf3442185b5891e15450d6e3058aeff6796fetom            }
41673c9cf3442185b5891e15450d6e3058aeff6796fetom
41683c9cf3442185b5891e15450d6e3058aeff6796fetom            /* The range this .debug_frame FDE covers has been already
41693c9cf3442185b5891e15450d6e3058aeff6796fetom               covered in .eh_frame section.  Don't add it from .debug_frame
41703c9cf3442185b5891e15450d6e3058aeff6796fetom               section again.  */
41713c9cf3442185b5891e15450d6e3058aeff6796fetom            if (lo <= hi)
41723c9cf3442185b5891e15450d6e3058aeff6796fetom               continue;
41733c9cf3442185b5891e15450d6e3058aeff6796fetom         }
41743c9cf3442185b5891e15450d6e3058aeff6796fetom
4175c6d3f6f0aec8607dded979fd15a9876a486ec682sewardj         adi.encoding      = the_CIEs[cie].address_encoding;
41763c9cf3442185b5891e15450d6e3058aeff6796fetom         adi.ehframe_image = frame_image;
41773c9cf3442185b5891e15450d6e3058aeff6796fetom         adi.ehframe_avma  = frame_avma;
4178402c9eed11b9b60c6e134d05db938e395466cf99tom         adi.text_bias     = di->text_debug_bias;
41798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj         adi.got_avma      = di->got_avma;
41801936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj
4181b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj         if (di->trace_cfi)
41823646a495f974e4aacf329e7539a0d584962ff6f6sewardj            show_CF_instructions( fde_instrs, fde_ilen, &adi,
41833646a495f974e4aacf329e7539a0d584962ff6f6sewardj                                  the_CIEs[cie].code_a_f,
41843646a495f974e4aacf329e7539a0d584962ff6f6sewardj                                  the_CIEs[cie].data_a_f );
4185325ec87d4c86014648d5da7205bd9a7104eb9e63sewardj
41865c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj	 initUnwindContext(&ctx);
4187726baecdd1d6614ef65a8d84217cfccde951be66sewardj         ctx.code_a_f = the_CIEs[cie].code_a_f;
4188726baecdd1d6614ef65a8d84217cfccde951be66sewardj         ctx.data_a_f = the_CIEs[cie].data_a_f;
418935165537cfa2da18220e55e23f21228c1e2591fesewardj         ctx.initloc  = fde_initloc;
4190726baecdd1d6614ef65a8d84217cfccde951be66sewardj         ctx.ra_reg   = the_CIEs[cie].ra_reg;
41919c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj         ctx.exprs    = VG_(newXA)( ML_(dinfo_zalloc), "di.rcid.1",
41929c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                                    ML_(dinfo_free),
419372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj                                    sizeof(CfiExpr) );
41948eb413204b3d80f52d207e8292c952f74faa2ca6sewardj
41953646a495f974e4aacf329e7539a0d584962ff6f6sewardj	 /* Run the CIE's instructions.  Ugly hack: if
41963646a495f974e4aacf329e7539a0d584962ff6f6sewardj            --debug-dump=frames is in effect, suppress output for
41973646a495f974e4aacf329e7539a0d584962ff6f6sewardj            these instructions since they will already have been shown
41983646a495f974e4aacf329e7539a0d584962ff6f6sewardj            at the time the CIE was first encountered.  Note, not
41993646a495f974e4aacf329e7539a0d584962ff6f6sewardj            thread safe - if this reader is ever made threaded, should
42003646a495f974e4aacf329e7539a0d584962ff6f6sewardj            fix properly. */
4201b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj	 { Bool hack = di->ddump_frames;
4202b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           di->ddump_frames = False;
42033646a495f974e4aacf329e7539a0d584962ff6f6sewardj           initUnwindContext(&restore_ctx);
42043646a495f974e4aacf329e7539a0d584962ff6f6sewardj           ok = run_CF_instructions(
4205b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                   di, False, &ctx, the_CIEs[cie].instrs,
42063646a495f974e4aacf329e7539a0d584962ff6f6sewardj                   the_CIEs[cie].ilen, 0, NULL, &adi
42073646a495f974e4aacf329e7539a0d584962ff6f6sewardj                );
4208b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj           di->ddump_frames = hack;
42093646a495f974e4aacf329e7539a0d584962ff6f6sewardj         }
42103646a495f974e4aacf329e7539a0d584962ff6f6sewardj         /* And now run the instructions for the FDE, starting from
42113646a495f974e4aacf329e7539a0d584962ff6f6sewardj            the state created by running the CIE preamble
42123646a495f974e4aacf329e7539a0d584962ff6f6sewardj            instructions. */
42138eb413204b3d80f52d207e8292c952f74faa2ca6sewardj         if (ok) {
42148eb413204b3d80f52d207e8292c952f74faa2ca6sewardj            restore_ctx = ctx;
42158eb413204b3d80f52d207e8292c952f74faa2ca6sewardj	    ok = run_CF_instructions(
4216b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj                    di, True, &ctx, fde_instrs, fde_ilen, fde_arange,
42171936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj                    &restore_ctx, &adi
42181936f8b3b201839583a39d0514049bcb1e3c3c2bsewardj                 );
4219b8b79addf04dd5d0b558916e26df0b1927cbd758sewardj            if (di->ddump_frames)
42203646a495f974e4aacf329e7539a0d584962ff6f6sewardj               VG_(printf)("\n");
42218eb413204b3d80f52d207e8292c952f74faa2ca6sewardj	 }
422272427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj
422372427fa91a5e05e3323b5a8a407bd8d7b04c75ccsewardj         VG_(deleteXA)( ctx.exprs );
42245c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj      }
42255c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   }
42265c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
42275c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   return;
42285c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
42295c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj   bad:
4230cbd2f03c5c549246a9a86dd57b7050825b52cf8dsewardj    if (!VG_(clo_xml) && VG_(clo_verbosity) > 1)
4231738856f99eea33d86ce91dcb1d6cd5b151e307casewardj       VG_(message)(Vg_UserMsg,
4232738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                    "Warning: %s in DWARF2 CFI reading\n", how);
42335c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj    return;
42345c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj}
42355c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
42368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#endif // defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris)
42375c638c2bda665e232ecf62b5443c93c3d6b7e06asewardj
42384bbdc9756d8750b77759b31da2dbebffaf957b5enjn/*--------------------------------------------------------------------*/
4239ea27e4627518665dd6c81213c0ba1f7ff0218e1anjn/*--- end                                                          ---*/
42404bbdc9756d8750b77759b31da2dbebffaf957b5enjn/*--------------------------------------------------------------------*/
4241