• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*--------------------------------------------------------------------*/
3 /*--- Read DWARF1/2/3/4 debug info.                    readdwarf.c ---*/
4 /*--------------------------------------------------------------------*/
5 
6 /*
7    This file is part of Valgrind, a dynamic binary instrumentation
8    framework.
9 
10    Copyright (C) 2000-2010 Julian Seward
11       jseward@acm.org
12 
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
15    published by the Free Software Foundation; either version 2 of the
16    License, or (at your option) any later version.
17 
18    This program is distributed in the hope that it will be useful, but
19    WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    General Public License for more details.
22 
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26    02111-1307, USA.
27 
28    The GNU General Public License is contained in the file COPYING.
29 */
30 
31 #if defined(VGO_linux) || defined(VGO_darwin)
32 
33 #include "pub_core_basics.h"
34 #include "pub_core_debuginfo.h"
35 #include "pub_core_libcbase.h"
36 #include "pub_core_libcassert.h"
37 #include "pub_core_libcprint.h"
38 #include "pub_core_options.h"
39 #include "pub_core_xarray.h"
40 #include "pub_core_tooliface.h"    /* VG_(needs) */
41 #include "priv_misc.h"             /* dinfo_zalloc/free/strdup */
42 #include "priv_d3basics.h"
43 #include "priv_tytypes.h"
44 #include "priv_storage.h"
45 #include "priv_readdwarf.h"        /* self */
46 
47 
48 /*------------------------------------------------------------*/
49 /*---                                                      ---*/
50 /*--- Read line number and CFI info from DWARF1, DWARF2    ---*/
51 /*--- and to some extent DWARF3 sections.                  ---*/
52 /*---                                                      ---*/
53 /*------------------------------------------------------------*/
54 
55 /*------------------------------------------------------------*/
56 /*--- Expanding arrays of words, for holding file name and ---*/
57 /*--- directory name arrays.                               ---*/
58 /*------------------------------------------------------------*/
59 
60 typedef
61    struct {
62       Word* tab;
63       UInt  tab_size;
64       UInt  tab_used;
65    }
66    WordArray;
67 
init_WordArray(WordArray * wa)68 static void init_WordArray ( WordArray* wa )
69 {
70    wa->tab      = NULL;
71    wa->tab_size = 0;
72    wa->tab_used = 0;
73 }
74 
free_WordArray(WordArray * wa)75 static void free_WordArray ( WordArray* wa )
76 {
77    if (wa->tab) {
78       vg_assert(wa->tab_size > 0);
79       ML_(dinfo_free)(wa->tab);
80    }
81    init_WordArray(wa);
82 }
83 
addto_WordArray(WordArray * wa,Word w)84 static void addto_WordArray ( WordArray* wa, Word w )
85 {
86    UInt  new_size, i;
87    Word* new_tab;
88 
89    if (0) VG_(printf)("<<ADD %p (new sz = %d) >>\n",
90                       (HChar*)w, wa->tab_used+1);
91 
92    if (wa->tab_used < wa->tab_size) {
93       /* fine */
94    } else {
95       /* expand array */
96       if (0) VG_(printf)("EXPAND ARRAY from %d\n", wa->tab_size);
97       vg_assert(wa->tab_used == wa->tab_size);
98       vg_assert( (wa->tab_size == 0 && wa->tab == NULL)
99                  || (wa->tab_size != 0 && wa->tab != NULL) );
100       new_size = wa->tab_size == 0 ? 8 : 2 * wa->tab_size;
101       new_tab  = ML_(dinfo_zalloc)("di.aWA.1", new_size * sizeof(Word));
102       vg_assert(new_tab != NULL);
103       for (i = 0; i < wa->tab_used; i++)
104          new_tab[i] = wa->tab[i];
105       wa->tab_size = new_size;
106       if (wa->tab)
107          ML_(dinfo_free)(wa->tab);
108       wa->tab = new_tab;
109    }
110 
111    vg_assert(wa->tab_used < wa->tab_size);
112    vg_assert(wa->tab_size > 0);
113    wa->tab[wa->tab_used] = w;
114    wa->tab_used++;
115 }
116 
index_WordArray(Bool * inRange,WordArray * wa,Int i)117 static Word index_WordArray ( /*OUT*/Bool* inRange, WordArray* wa, Int i )
118 {
119    vg_assert(inRange);
120    if (i >= 0 && i < wa->tab_used) {
121       *inRange = True;
122       return wa->tab[i];
123    } else {
124       *inRange = False;
125       return 0;
126    }
127 }
128 
129 
130 /*------------------------------------------------------------*/
131 /*--- Read DWARF2 format line number info.                 ---*/
132 /*------------------------------------------------------------*/
133 
134 /* Structure holding info extracted from the a .debug_line
135    section.  */
136 typedef struct
137 {
138   ULong  li_length;
139   UShort li_version;
140   ULong  li_header_length;
141   UChar  li_min_insn_length;
142   UChar  li_max_ops_per_insn;
143   UChar  li_default_is_stmt;
144   Int    li_line_base;
145   UChar  li_line_range;
146   UChar  li_opcode_base;
147 }
148 DebugLineInfo;
149 
150 /* Structure holding additional infos found from a .debug_info
151  * compilation unit block */
152 typedef struct
153 {
154   /* Feel free to add more members here if you need ! */
155   Char* compdir;   /* Compilation directory - points to .debug_info */
156   Char* name;      /* Main file name - points to .debug_info */
157   ULong stmt_list; /* Offset in .debug_line */
158   Bool  dw64;      /* 64-bit Dwarf? */
159 }
160 UnitInfo;
161 
162 /* Line number opcodes.  */
163 enum dwarf_line_number_ops
164   {
165     DW_LNS_extended_op = 0,
166     DW_LNS_copy = 1,
167     DW_LNS_advance_pc = 2,
168     DW_LNS_advance_line = 3,
169     DW_LNS_set_file = 4,
170     DW_LNS_set_column = 5,
171     DW_LNS_negate_stmt = 6,
172     DW_LNS_set_basic_block = 7,
173     DW_LNS_const_add_pc = 8,
174     DW_LNS_fixed_advance_pc = 9,
175     /* DWARF 3.  */
176     DW_LNS_set_prologue_end = 10,
177     DW_LNS_set_epilogue_begin = 11,
178     DW_LNS_set_isa = 12
179   };
180 
181 /* Line number extended opcodes.  */
182 enum dwarf_line_number_x_ops
183   {
184     DW_LNE_end_sequence = 1,
185     DW_LNE_set_address = 2,
186     DW_LNE_define_file = 3,
187     DW_LNE_set_discriminator = 4
188   };
189 
190 typedef struct
191 {
192   /* Information for the last statement boundary.
193    * Needed to calculate statement lengths. */
194   Addr  last_address;
195   UInt  last_file;
196   UInt  last_line;
197 
198   Addr  address;
199   UInt  file;
200   UInt  line;
201   UInt  column;
202   Int   is_stmt;
203   Int   basic_block;
204   UChar end_sequence;
205 } LineSMR;
206 
207 
208 /* FIXME: duplicated in readdwarf3.c */
209 static
read_leb128(UChar * data,Int * length_return,Int sign)210 ULong read_leb128 ( UChar* data, Int* length_return, Int sign )
211 {
212   ULong  result = 0;
213   UInt   num_read = 0;
214   Int    shift = 0;
215   UChar  byte;
216 
217   vg_assert(sign == 0 || sign == 1);
218 
219   do
220     {
221       byte = * data ++;
222       num_read ++;
223 
224       result |= ((ULong)(byte & 0x7f)) << shift;
225 
226       shift += 7;
227 
228     }
229   while (byte & 0x80);
230 
231   if (length_return != NULL)
232     * length_return = num_read;
233 
234   if (sign && (shift < 64) && (byte & 0x40))
235     result |= -(1ULL << shift);
236 
237   return result;
238 }
239 
240 /* Small helper functions easier to use
241  * value is returned and the given pointer is
242  * moved past end of leb128 data */
243 /* FIXME: duplicated in readdwarf3.c */
read_leb128U(UChar ** data)244 static ULong read_leb128U( UChar **data )
245 {
246   Int len;
247   ULong val = read_leb128( *data, &len, 0 );
248   *data += len;
249   return val;
250 }
251 
252 /* Same for signed data */
253 /* FIXME: duplicated in readdwarf3.c */
read_leb128S(UChar ** data)254 static Long read_leb128S( UChar **data )
255 {
256    Int len;
257    ULong val = read_leb128( *data, &len, 1 );
258    *data += len;
259    return (Long)val;
260 }
261 
262 /* Read what the DWARF3 spec calls an "initial length field".  This
263    uses up either 4 or 12 bytes of the input and produces a 32-bit or
264    64-bit number respectively.
265 
266    Read 32-bit value from p.  If it is 0xFFFFFFFF, instead read a
267    64-bit bit value from p+4.  This is used in 64-bit dwarf to encode
268    some table lengths.
269 
270    XXX this is a hack: the endianness of the initial length field is
271    specified by the DWARF we're reading.  This happens to work only
272    because we don't do cross-arch jitting, hence this code runs on a
273    platform of the same endianness as the DWARF it is reading.  Same
274    applies for initial lengths for CIE/FDEs and probably in zillions
275    of other places -- to be precise, exactly the places where
276    binutils/dwarf.c calls byte_get().
277 */
read_initial_length_field(UChar * p_img,Bool * is64)278 static ULong read_initial_length_field ( UChar* p_img, /*OUT*/Bool* is64 )
279 {
280    UInt w32 = *((UInt*)p_img);
281    if (w32 == 0xFFFFFFFF) {
282       *is64 = True;
283       return *((ULong*)(p_img+4));
284    } else {
285       *is64 = False;
286       return (ULong)w32;
287    }
288 }
289 
290 
291 static LineSMR state_machine_regs;
292 
293 static
reset_state_machine(Int is_stmt)294 void reset_state_machine ( Int is_stmt )
295 {
296    if (0) VG_(printf)("smr.a := %p (reset)\n", NULL );
297    state_machine_regs.last_address = 0;
298    state_machine_regs.last_file = 1;
299    state_machine_regs.last_line = 1;
300    state_machine_regs.address = 0;
301    state_machine_regs.file = 1;
302    state_machine_regs.line = 1;
303    state_machine_regs.column = 0;
304    state_machine_regs.is_stmt = is_stmt;
305    state_machine_regs.basic_block = 0;
306    state_machine_regs.end_sequence = 0;
307 }
308 
309 /* Look up a directory name, or return NULL if unknown. */
310 static
lookupDir(Int filename_index,WordArray * fnidx2dir,WordArray * dirnames)311 Char* lookupDir ( Int filename_index,
312                   WordArray* fnidx2dir,
313                   WordArray* dirnames )
314 {
315    Bool inRange;
316    Word diridx, dirname;
317 
318    diridx = index_WordArray( &inRange, fnidx2dir, filename_index );
319    if (!inRange) goto bad;
320 
321    dirname = index_WordArray( &inRange, dirnames, (Int)diridx );
322    if (!inRange) goto bad;
323 
324    return (Char*)dirname;
325   bad:
326    return NULL;
327 }
328 
329 ////////////////////////////////////////////////////////////////////
330 ////////////////////////////////////////////////////////////////////
331 
332 /* Handled an extended line op starting at 'data'.  Returns the number
333    of bytes that 'data' should be advanced by. */
334 static
process_extended_line_op(struct _DebugInfo * di,WordArray * filenames,WordArray * dirnames,WordArray * fnidx2dir,UChar * data,Int is_stmt)335 Word process_extended_line_op( struct _DebugInfo* di,
336                                WordArray* filenames,
337                                WordArray* dirnames,
338                                WordArray* fnidx2dir,
339                                UChar* data, Int is_stmt)
340 {
341    UChar  op_code;
342    Int    bytes_read;
343    UInt   len;
344    UChar* name;
345    Addr   adr;
346 
347    len = read_leb128 (data, & bytes_read, 0);
348    data += bytes_read;
349 
350    if (len == 0) {
351       VG_(message)(Vg_UserMsg,
352                    "Warning: DWARF2 reader: "
353                    "Badly formed extended line op encountered\n");
354       return (Word)bytes_read;
355    }
356 
357    len += bytes_read;
358    op_code = * data ++;
359 
360    if (0) VG_(printf)("dwarf2: ext OPC: %d\n", op_code);
361 
362    switch (op_code) {
363       case DW_LNE_end_sequence:
364          if (0) VG_(printf)("1001: si->o %#lx, smr.a %#lx\n",
365                             di->text_debug_bias, state_machine_regs.address );
366          /* JRS: added for compliance with spec; is pointless due to
367             reset_state_machine below */
368          state_machine_regs.end_sequence = 1;
369 
370          if (state_machine_regs.is_stmt) {
371             if (state_machine_regs.last_address) {
372                Bool inRange = False;
373                Char* filename
374                   = (Char*)index_WordArray( &inRange, filenames,
375                                             state_machine_regs.last_file);
376                if (!inRange || !filename)
377                   filename = "???";
378                ML_(addLineInfo) (
379                   di,
380                   filename,
381                   lookupDir( state_machine_regs.last_file,
382                              fnidx2dir, dirnames ),
383                   di->text_debug_bias + state_machine_regs.last_address,
384                   di->text_debug_bias + state_machine_regs.address,
385                   state_machine_regs.last_line, 0
386                );
387             }
388          }
389          reset_state_machine (is_stmt);
390          if (di->ddump_line)
391             VG_(printf)("  Extended opcode %d: End of Sequence\n\n",
392                         (Int)op_code);
393          break;
394 
395       case DW_LNE_set_address:
396          adr = *((Addr *)data);
397          state_machine_regs.address = adr;
398          if (di->ddump_line)
399             VG_(printf)("  Extended opcode %d: set Address to 0x%lx\n",
400                         (Int)op_code, (Addr)adr);
401          break;
402 
403       case DW_LNE_define_file:
404          name = data;
405          addto_WordArray( filenames, (Word)ML_(addStr)(di,name,-1) );
406          data += VG_(strlen) ((char *) data) + 1;
407          read_leb128 (data, & bytes_read, 0);
408          data += bytes_read;
409          read_leb128 (data, & bytes_read, 0);
410          data += bytes_read;
411          read_leb128 (data, & bytes_read, 0);
412          if (di->ddump_line)
413             VG_(printf)("  DWARF2-line: set_address\n");
414          break;
415 
416       case DW_LNE_set_discriminator:
417          read_leb128 (data, & bytes_read, 0);
418          data += bytes_read;
419          break;
420 
421       default:
422          if (di->ddump_line)
423             VG_(printf)("process_extended_line_op:default\n");
424          break;
425    }
426 
427    return (Word)len;
428 }
429 
430 ////////////////////////////////////////////////////////////////////
431 ////////////////////////////////////////////////////////////////////
432 
433 /* read a .debug_line section block for a compilation unit
434  *
435  * Input:   - theBlock must point to the start of the block
436  *            for the given compilation unit
437  *          - ui contains additional info like the compilation dir
438  *            for this unit
439  *
440  * Output: - si debug info structures get updated
441  */
442 static
read_dwarf2_lineblock(struct _DebugInfo * di,UnitInfo * ui,UChar * theBlock,Int noLargerThan)443 void read_dwarf2_lineblock ( struct _DebugInfo* di,
444                              UnitInfo* ui,
445                              UChar*    theBlock, /* IMAGE */
446                              Int       noLargerThan )
447 {
448    Int            i;
449    DebugLineInfo  info;
450    UChar*         standard_opcodes;
451    UChar*         end_of_sequence;
452    Bool           is64;
453    WordArray      filenames;
454    WordArray      dirnames;
455    WordArray      fnidx2dir;
456 
457    UChar*         external = theBlock;
458    UChar*         data = theBlock;
459 
460    /* filenames is an array of file names harvested from the DWARF2
461       info.  Entry [0] is NULL and is never referred to by the state
462       machine.
463 
464       Similarly, dirnames is an array of directory names.  Entry [0]
465       is also NULL and denotes "we don't know what the path is", since
466       that is different from "the path is the empty string".  Unlike
467       the file name table, the state machine does refer to entry [0],
468       which basically means "." ("the current directory of the
469       compilation", whatever that means, according to the DWARF3
470       spec.)
471 
472       fnidx2dir is an array of indexes into the dirnames table.
473       (confused yet?)  filenames[] and fnidx2dir[] are indexed
474       together.  That is, for some index i in the filename table, then
475 
476          the filename  is filenames[i]
477          the directory is dirnames[ fnidx2dir[i] ] */
478 
479    /* Fails due to gcc padding ...
480    vg_assert(sizeof(DWARF2_External_LineInfo)
481              == sizeof(DWARF2_Internal_LineInfo));
482    */
483 
484    init_WordArray(&filenames);
485    init_WordArray(&dirnames);
486    init_WordArray(&fnidx2dir);
487 
488    /* DWARF2 starts numbering filename entries at 1, so we need to
489       add a dummy zeroth entry to the table.  The zeroth dirnames
490       entry denotes 'current directory of compilation' so we might
491       as well make the fnidx2dir zeroth entry denote that.
492    */
493    addto_WordArray( &filenames, (Word)NULL );
494 
495    if (ui->compdir)
496       addto_WordArray( &dirnames, (Word)ML_(addStr)(di, ui->compdir, -1) );
497    else
498       addto_WordArray( &dirnames, (Word)ML_(addStr)(di, ".", -1) );
499 
500    addto_WordArray( &fnidx2dir, (Word)0 );  /* compilation dir */
501 
502    info.li_length = read_initial_length_field( external, &is64 );
503    external += is64 ? 12 : 4;
504    if (di->ddump_line)
505       VG_(printf)("  Length:                      %llu\n",
506                   info.li_length);
507 
508    /* Check the length of the block.  */
509    if (info.li_length > noLargerThan) {
510       ML_(symerr)(di, True,
511                   "DWARF line info appears to be corrupt "
512                   "- the section is too small");
513       goto out;
514    }
515 
516    /* Check its version number.  */
517    info.li_version = * ((UShort *)external);
518    external += 2;
519    if (di->ddump_line)
520       VG_(printf)("  DWARF Version:               %d\n",
521                   (Int)info.li_version);
522 
523    if (info.li_version != 2 && info.li_version != 3 && info.li_version != 4) {
524       ML_(symerr)(di, True,
525                   "Only DWARF version 2, 3 and 4 line info "
526                   "is currently supported.");
527       goto out;
528    }
529 
530    info.li_header_length = ui->dw64 ? *((ULong*)external)
531                                     : (ULong)(*((UInt*)external));
532    external += ui->dw64 ? 8 : 4;
533    if (di->ddump_line)
534       VG_(printf)("  Prologue Length:             %llu\n",
535                   info.li_header_length);
536 
537    info.li_min_insn_length = * ((UChar *)external);
538    external += 1;
539    if (di->ddump_line)
540       VG_(printf)("  Minimum Instruction Length:  %d\n",
541                   (Int)info.li_min_insn_length);
542 
543    /* We only support machines with one opcode per instruction
544       for now. If we ever want to support VLIW machines there is
545       code to handle multiple opcodes per instruction in the
546       patch attached to BZ#233595.
547    */
548    if (info.li_version >= 4) {
549       info.li_max_ops_per_insn = * ((UChar *)external);
550       if (info.li_max_ops_per_insn != 1) {
551          ML_(symerr)(di, True,
552                      "Invalid Maximum Ops Per Insn in line info.");
553          goto out;
554       }
555       external += 1;
556       if (di->ddump_line)
557          VG_(printf)("  Maximum Ops Per Insn:        %d\n",
558                   (Int)info.li_max_ops_per_insn);
559    } else {
560       info.li_max_ops_per_insn = 1;
561    }
562 
563    info.li_default_is_stmt = * ((UChar *)external);
564    external += 1;
565    if (di->ddump_line)
566       VG_(printf)("  Initial value of 'is_stmt':  %d\n",
567                   (Int)info.li_default_is_stmt);
568 
569    /* Josef Weidendorfer (20021021) writes:
570 
571       It seems to me that the Intel Fortran compiler generates bad
572       DWARF2 line info code: It sets "is_stmt" of the state machine in
573       the the line info reader to be always false. Thus, there is
574       never a statement boundary generated and therefore never a
575       instruction range/line number mapping generated for valgrind.
576 
577       Please have a look at the DWARF2 specification, Ch. 6.2
578       (x86.ddj.com/ftp/manuals/tools/dwarf.pdf).  Perhaps I understand
579       this wrong, but I don't think so.
580 
581       I just had a look at the GDB DWARF2 reader...  They completely
582       ignore "is_stmt" when recording line info ;-) That's the reason
583       "objdump -S" works on files from the the intel fortran compiler.
584 
585       Therefore: */
586    info.li_default_is_stmt = True;
587 
588    /* JRS: changed (UInt*) to (UChar*) */
589    info.li_line_base = * ((UChar *)external);
590    info.li_line_base = (Int)(signed char)info.li_line_base;
591    external += 1;
592    if (di->ddump_line)
593       VG_(printf)("  Line Base:                   %d\n",
594                   info.li_line_base);
595 
596    info.li_line_range = * ((UChar *)external);
597    external += 1;
598    if (di->ddump_line)
599       VG_(printf)("  Line Range:                  %d\n",
600                   (Int)info.li_line_range);
601 
602    info.li_opcode_base = * ((UChar *)external);
603    external += 1;
604    if (di->ddump_line)
605       VG_(printf)("  Opcode Base:                 %d\n\n",
606                   info.li_opcode_base);
607 
608    if (0) VG_(printf)("dwarf2: line base: %d, range %d, opc base: %d\n",
609                       (Int)info.li_line_base,
610                       (Int)info.li_line_range,
611                       (Int)info.li_opcode_base);
612 
613    end_of_sequence = data + info.li_length
614                           + (is64 ? 12 : 4);
615 
616    reset_state_machine (info.li_default_is_stmt);
617 
618    /* Read the contents of the Opcodes table.  */
619    standard_opcodes = external;
620    if (di->ddump_line) {
621       VG_(printf)(" Opcodes:\n");
622       for (i = 1; i < (Int)info.li_opcode_base; i++) {
623          VG_(printf)("  Opcode %d has %d args\n",
624                      i, (Int)standard_opcodes[i-1]);
625       }
626       VG_(printf)("\n");
627    }
628 
629    /* Read the contents of the Directory table.  */
630    data = standard_opcodes + info.li_opcode_base - 1;
631 
632    if (di->ddump_line)
633       VG_(printf)(" The Directory Table%s\n",
634                   *data == 0 ? " is empty." : ":" );
635 
636    while (* data != 0) {
637 
638 #     define NBUF 4096
639       static Char buf[NBUF];
640 
641       if (di->ddump_line)
642          VG_(printf)("  %s\n", data);
643 
644       /* If data[0] is '/', then 'data' is an absolute path and we
645          don't mess with it.  Otherwise, if we can, construct the
646          'path ui->compdir' ++ "/" ++ 'data'. */
647 
648       if (*data != '/'
649           /* not an absolute path */
650           && ui->compdir != NULL
651           /* actually got something sensible for compdir */
652           && VG_(strlen)(ui->compdir) + VG_(strlen)(data) + 5/*paranoia*/ < NBUF
653           /* it's short enough to concatenate */)
654       {
655          buf[0] = 0;
656          VG_(strcat)(buf, ui->compdir);
657          VG_(strcat)(buf, "/");
658          VG_(strcat)(buf, data);
659          vg_assert(VG_(strlen)(buf) < NBUF);
660          addto_WordArray( &dirnames, (Word)ML_(addStr)(di,buf,-1) );
661          if (0) VG_(printf)("rel path  %s\n", buf);
662       } else {
663          /* just use 'data'. */
664          addto_WordArray( &dirnames, (Word)ML_(addStr)(di,data,-1) );
665          if (0) VG_(printf)("abs path  %s\n", data);
666       }
667 
668       data += VG_(strlen)(data) + 1;
669 
670 #     undef NBUF
671    }
672 
673    if (di->ddump_line)
674       VG_(printf)("\n");
675 
676    if (*data != 0) {
677       ML_(symerr)(di, True,
678                   "can't find NUL at end of DWARF2 directory table");
679       goto out;
680    }
681    data ++;
682 
683    /* Read the contents of the File Name table.  This produces a bunch
684       of file names, and for each, an index to the corresponding
685       directory name entry. */
686    if (di->ddump_line) {
687       VG_(printf)(" The File Name Table:\n");
688       VG_(printf)("  Entry	Dir	Time	Size	Name\n");
689    }
690 
691    i = 1;
692    while (* data != 0) {
693       UChar* name;
694       Int    bytes_read, diridx;
695       Int    uu_time, uu_size; /* unused, and a guess */
696       name = data;
697       data += VG_(strlen) ((Char *) data) + 1;
698 
699       diridx = read_leb128 (data, & bytes_read, 0);
700       data += bytes_read;
701       uu_time = read_leb128 (data, & bytes_read, 0);
702       data += bytes_read;
703       uu_size = read_leb128 (data, & bytes_read, 0);
704       data += bytes_read;
705 
706       addto_WordArray( &filenames, (Word)ML_(addStr)(di,name,-1) );
707       addto_WordArray( &fnidx2dir, (Word)diridx );
708       if (0) VG_(printf)("file %s diridx %d\n", name, diridx );
709       if (di->ddump_line)
710          VG_(printf)("  %d\t%d\t%d\t%d\t%s\n",
711                      i, diridx, uu_time, uu_size, name);
712       i++;
713    }
714 
715    if (di->ddump_line)
716       VG_(printf)("\n");
717 
718    if (*data != 0) {
719       ML_(symerr)(di, True,
720                   "can't find NUL at end of DWARF2 file name table");
721       goto out;
722    }
723    data ++;
724 
725    if (di->ddump_line)
726       VG_(printf)(" Line Number Statements:\n");
727 
728    /* Now display the statements.  */
729 
730    while (data < end_of_sequence) {
731 
732       UChar op_code;
733       Int           adv;
734       Int           bytes_read;
735 
736       op_code = * data ++;
737 
738       if (0) VG_(printf)("dwarf2: OPC: %d\n", op_code);
739 
740       if (op_code >= info.li_opcode_base) {
741 
742          Int advAddr;
743          op_code -= info.li_opcode_base;
744          adv      = (op_code / info.li_line_range)
745                        * info.li_min_insn_length;
746          advAddr = adv;
747          state_machine_regs.address += adv;
748 
749          if (0) VG_(printf)("smr.a += %#x\n", adv );
750          adv = (op_code % info.li_line_range) + info.li_line_base;
751          if (0) VG_(printf)("1002: di->o %#lx, smr.a %#lx\n",
752                             di->text_debug_bias, state_machine_regs.address );
753          state_machine_regs.line += adv;
754 
755          if (di->ddump_line)
756             VG_(printf)("  Special opcode %d: advance Address by %d "
757                         "to 0x%lx and Line by %d to %d\n",
758                         (Int)op_code, advAddr, state_machine_regs.address,
759                         (Int)adv, (Int)state_machine_regs.line );
760 
761          if (state_machine_regs.is_stmt) {
762             /* only add a statement if there was a previous boundary */
763             if (state_machine_regs.last_address) {
764                Bool inRange = False;
765                Char* filename
766                   = (Char*)index_WordArray( &inRange, &filenames,
767                                             state_machine_regs.last_file);
768                if (!inRange || !filename)
769                   filename = "???";
770                ML_(addLineInfo)(
771                   di,
772                   filename,
773                   lookupDir( state_machine_regs.last_file,
774                              &fnidx2dir, &dirnames ),
775                   di->text_debug_bias + state_machine_regs.last_address,
776                   di->text_debug_bias + state_machine_regs.address,
777                   state_machine_regs.last_line,
778                   0
779                );
780             }
781             state_machine_regs.last_address = state_machine_regs.address;
782             state_machine_regs.last_file = state_machine_regs.file;
783             state_machine_regs.last_line = state_machine_regs.line;
784          }
785 
786       }
787 
788       else { /* ! (op_code >= info.li_opcode_base) */
789 
790       switch (op_code) {
791          case DW_LNS_extended_op:
792             data += process_extended_line_op (
793                        di, &filenames, &dirnames, &fnidx2dir,
794                        data, info.li_default_is_stmt);
795             break;
796 
797          case DW_LNS_copy:
798             if (0) VG_(printf)("1002: di->o %#lx, smr.a %#lx\n",
799                                di->text_debug_bias, state_machine_regs.address );
800             if (state_machine_regs.is_stmt) {
801                /* only add a statement if there was a previous boundary */
802                if (state_machine_regs.last_address) {
803                   Bool inRange = False;
804                   Char* filename
805                      = (Char*)index_WordArray( &inRange, &filenames,
806                                                state_machine_regs.last_file );
807                   if (!inRange || !filename)
808                      filename = "???";
809                   ML_(addLineInfo)(
810                      di,
811                      filename,
812                      lookupDir( state_machine_regs.last_file,
813                                 &fnidx2dir, &dirnames ),
814                      di->text_debug_bias + state_machine_regs.last_address,
815                      di->text_debug_bias + state_machine_regs.address,
816                      state_machine_regs.last_line,
817                      0
818                   );
819                }
820                state_machine_regs.last_address = state_machine_regs.address;
821                state_machine_regs.last_file = state_machine_regs.file;
822                state_machine_regs.last_line = state_machine_regs.line;
823             }
824             state_machine_regs.basic_block = 0; /* JRS added */
825             if (di->ddump_line)
826                VG_(printf)("  Copy\n");
827             break;
828 
829          case DW_LNS_advance_pc:
830             adv = info.li_min_insn_length
831                      * read_leb128 (data, & bytes_read, 0);
832             data += bytes_read;
833             state_machine_regs.address += adv;
834             if (0) VG_(printf)("smr.a += %#x\n", adv );
835             if (di->ddump_line)
836                VG_(printf)("  Advance PC by %d to 0x%lx\n",
837                            (Int)adv, state_machine_regs.address);
838             break;
839 
840          case DW_LNS_advance_line:
841             adv = read_leb128 (data, & bytes_read, 1);
842             data += bytes_read;
843             state_machine_regs.line += adv;
844             if (di->ddump_line)
845                VG_(printf)("  Advance Line by %d to %d\n",
846                            (Int)adv, (Int)state_machine_regs.line);
847             break;
848 
849          case DW_LNS_set_file:
850             adv = read_leb128 (data, & bytes_read, 0);
851             data += bytes_read;
852             state_machine_regs.file = adv;
853             if (di->ddump_line)
854                VG_(printf)("  Set File Name to entry %d in the File Name Table\n",
855                            (Int)adv);
856             break;
857 
858          case DW_LNS_set_column:
859             adv = read_leb128 (data, & bytes_read, 0);
860             data += bytes_read;
861             state_machine_regs.column = adv;
862             if (di->ddump_line)
863                VG_(printf)("  DWARF2-line: set_column\n");
864             break;
865 
866          case DW_LNS_negate_stmt:
867             adv = state_machine_regs.is_stmt;
868             adv = ! adv;
869             state_machine_regs.is_stmt = adv;
870             if (di->ddump_line)
871                VG_(printf)("  DWARF2-line: negate_stmt\n");
872             break;
873 
874          case DW_LNS_set_basic_block:
875             state_machine_regs.basic_block = 1;
876             if (di->ddump_line)
877                VG_(printf)("  DWARF2-line: set_basic_block\n");
878             break;
879 
880          case DW_LNS_const_add_pc:
881             adv = (((255 - info.li_opcode_base) / info.li_line_range)
882                    * info.li_min_insn_length);
883             state_machine_regs.address += adv;
884             if (0) VG_(printf)("smr.a += %#x\n", adv );
885             if (di->ddump_line)
886                VG_(printf)("  Advance PC by constant %d to 0x%lx\n",
887                            (Int)adv, (Addr)state_machine_regs.address);
888             break;
889 
890          case DW_LNS_fixed_advance_pc:
891             /* XXX: Need something to get 2 bytes */
892             adv = *((UShort *)data);
893             data += 2;
894             state_machine_regs.address += adv;
895             if (0) VG_(printf)("smr.a += %#x\n", adv );
896             if (di->ddump_line)
897                VG_(printf)("  DWARF2-line: fixed_advance_pc\n");
898             break;
899 
900          case DW_LNS_set_prologue_end:
901             if (di->ddump_line)
902                VG_(printf)("  DWARF2-line: set_prologue_end\n");
903             break;
904 
905          case DW_LNS_set_epilogue_begin:
906             if (di->ddump_line)
907                VG_(printf)("  DWARF2-line: set_epilogue_begin\n");
908             break;
909 
910          case DW_LNS_set_isa:
911             /*adv =*/ read_leb128 (data, & bytes_read, 0);
912             data += bytes_read;
913             if (di->ddump_line)
914                VG_(printf)("  DWARF2-line: set_isa\n");
915             break;
916 
917          default: {
918             Int j;
919             for (j = standard_opcodes[op_code - 1]; j > 0 ; --j) {
920                read_leb128 (data, &bytes_read, 0);
921                data += bytes_read;
922             }
923             if (di->ddump_line)
924                VG_(printf)("  Unknown opcode %d\n", (Int)op_code);
925             break;
926          }
927       } /* switch (op_code) */
928 
929       } /* if (op_code >= info.li_opcode_base) */
930 
931    } /* while (data < end_of_sequence) */
932 
933    if (di->ddump_line)
934       VG_(printf)("\n");
935 
936   out:
937    free_WordArray(&filenames);
938    free_WordArray(&dirnames);
939    free_WordArray(&fnidx2dir);
940 }
941 
942 ////////////////////////////////////////////////////////////////////
943 ////////////////////////////////////////////////////////////////////
944 
945 /* Return abbrev for given code
946  * Returned pointer points to the tag
947  * */
lookup_abbrev(UChar * p,UInt acode)948 static UChar* lookup_abbrev( UChar* p, UInt acode )
949 {
950    UInt code;
951    UInt name;
952    for( ; ; ) {
953       code = read_leb128U( &p );
954       if ( code == acode )
955          return p;
956       read_leb128U( &p ); /* skip tag */
957       p++;                /* skip has_children flag */
958       do {
959          name = read_leb128U( &p ); /* name */
960          read_leb128U( &p );   /* form */
961       }
962       while( name != 0 ); /* until name == form == 0 */
963    }
964    return NULL;
965 }
966 
967 /* Read general information for a particular compile unit block in
968  * the .debug_info section.
969  *
970  * Input: - unitblock is the start of a compilation
971  *          unit block in .debuginfo section
972  *        - debugabbrev is start of .debug_abbrev section
973  *        - debugstr is start of .debug_str section
974  *
975  * Output: Fill members of ui pertaining to the compilation unit:
976  *         - ui->name is the name of the compilation unit
977  *         - ui->compdir is the compilation unit directory
978  *         - ui->stmt_list is the offset in .debug_line section
979  *                for the dbginfos of this compilation unit
980  *
981  * Note : the output strings are not allocated and point
982  * directly to the memory-mapped section.
983  */
984 static
read_unitinfo_dwarf2(UnitInfo * ui,UChar * unitblock_img,UChar * debugabbrev_img,UChar * debugstr_img)985 void read_unitinfo_dwarf2( /*OUT*/UnitInfo* ui,
986                                   UChar*    unitblock_img,
987                                   UChar*    debugabbrev_img,
988                                   UChar*    debugstr_img )
989 {
990    UInt   acode, abcode;
991    ULong  atoffs, blklen;
992    Int    level;
993    UShort ver;
994 
995    UChar addr_size;
996    UChar* p = unitblock_img;
997    UChar* end_img;
998    UChar* abbrev_img;
999 
1000    VG_(memset)( ui, 0, sizeof( UnitInfo ) );
1001    ui->stmt_list = -1LL;
1002 
1003    /* Read the compilation unit header in .debug_info section - See p 70 */
1004 
1005    /* This block length */
1006    blklen = read_initial_length_field( p, &ui->dw64 );
1007    p += ui->dw64 ? 12 : 4;
1008 
1009    /* version should be 2, 3 or 4 */
1010    ver = *((UShort*)p);
1011    p += 2;
1012 
1013    /* get offset in abbrev */
1014    atoffs = ui->dw64 ? *((ULong*)p) : (ULong)(*((UInt*)p));
1015    p += ui->dw64 ? 8 : 4;
1016 
1017    /* Address size */
1018    addr_size = *p;
1019    p += 1;
1020 
1021    end_img     = unitblock_img
1022                  + blklen + (ui->dw64 ? 12 : 4); /* End of this block */
1023    level       = 0;                        /* Level in the abbrev tree */
1024    abbrev_img  = debugabbrev_img
1025                  + atoffs; /* Abbreviation data for this block */
1026 
1027    /* Read the compilation unit entries */
1028    while ( p < end_img ) {
1029       Bool has_child;
1030       UInt tag;
1031 
1032       acode = read_leb128U( &p ); /* abbreviation code */
1033       if ( acode == 0 ) {
1034          /* NULL entry used for padding - or last child for a sequence
1035             - see para 7.5.3 */
1036          level--;
1037          continue;
1038       }
1039 
1040       /* Read abbreviation header */
1041       abcode = read_leb128U( &abbrev_img ); /* abbreviation code */
1042       if ( acode != abcode ) {
1043          /* We are in in children list, and must rewind to a
1044           * previously declared abbrev code.  This code works but is
1045           * not triggered since we shortcut the parsing once we have
1046           * read the compile_unit block.  This should only occur when
1047           * level > 0 */
1048          abbrev_img = lookup_abbrev( debugabbrev_img + atoffs, acode );
1049       }
1050 
1051       tag = read_leb128U( &abbrev_img );
1052       has_child = *(abbrev_img++) == 1; /* DW_CHILDREN_yes */
1053 
1054       if ( has_child )
1055          level++;
1056 
1057       /* And loop on entries */
1058       for ( ; ; ) {
1059          /* Read entry definition */
1060          UInt  name, form;
1061          ULong cval = -1LL;  /* Constant value read */
1062          Char  *sval = NULL; /* String value read */
1063          name = read_leb128U( &abbrev_img );
1064          form = read_leb128U( &abbrev_img );
1065          if ( name == 0 )
1066             break;
1067 
1068          /* Read data */
1069          /* Attributes encoding explained p 71 */
1070          if ( form == 0x16 /* FORM_indirect */ )
1071             form = read_leb128U( &p );
1072          /* Decode form. For most kinds, Just skip the amount of data since
1073             we don't use it for now */
1074          /* JRS 9 Feb 06: This now handles 64-bit DWARF too.  In
1075             64-bit DWARF, lineptr (and loclistptr,macptr,rangelistptr
1076             classes) use FORM_data8, not FORM_data4.  Also,
1077             FORM_ref_addr and FORM_strp are 64-bit values, not 32-bit
1078             values. */
1079          /* TJH 27 Apr 10: in DWARF 4 lineptr (and loclistptr,macptr,
1080             rangelistptr classes) use FORM_sec_offset which is 64 bits
1081             in 64 bit DWARF and 32 bits in 32 bit DWARF. */
1082          switch( form ) {
1083             /* Those cases extract the data properly */
1084             case 0x05: /* FORM_data2 */     cval = *((UShort*)p); p +=2; break;
1085             case 0x06: /* FORM_data4 */     cval = *((UInt*)p);p +=4; break;
1086             case 0x0e: /* FORM_strp */      /* pointer in .debug_str */
1087                        /* 2006-01-01: only generate a value if
1088                           debugstr is non-NULL (which means that a
1089                           debug_str section was found) */
1090                                             if (debugstr_img && !ui->dw64)
1091                                                sval = debugstr_img + *((UInt*)p);
1092                                             if (debugstr_img && ui->dw64)
1093                                                sval = debugstr_img + *((ULong*)p);
1094                                             p += ui->dw64 ? 8 : 4;
1095                                             break;
1096             case 0x08: /* FORM_string */    sval = (Char*)p;
1097                                             p += VG_(strlen)((Char*)p) + 1; break;
1098             case 0x0b: /* FORM_data1 */     cval = *p; p++; break;
1099             case 0x17: /* FORM_sec_offset */if (ui->dw64) {
1100                                                cval = *((ULong*)p); p += 8;
1101                                             } else {
1102                                                cval = *((UInt*)p); p += 4;
1103                                             }; break;
1104             /* TODO : Following ones just skip data - implement if you need */
1105             case 0x01: /* FORM_addr */      p += addr_size; break;
1106             case 0x03: /* FORM_block2 */    p += *((UShort*)p) + 2; break;
1107             case 0x04: /* FORM_block4 */    p += *((UInt*)p) + 4; break;
1108             case 0x07: /* FORM_data8 */     if (ui->dw64) cval = *((ULong*)p);
1109                                             p += 8; break;
1110                        /* perhaps should assign unconditionally to cval? */
1111             case 0x09: /* FORM_block */     p += read_leb128U( &p ); break;
1112             case 0x0a: /* FORM_block1 */    p += *p + 1; break;
1113             case 0x0c: /* FORM_flag */      p++; break;
1114             case 0x0d: /* FORM_sdata */     read_leb128S( &p ); break;
1115             case 0x0f: /* FORM_udata */     read_leb128U( &p ); break;
1116             case 0x10: /* FORM_ref_addr */  p += ui->dw64 ? 8 : 4; break;
1117             case 0x11: /* FORM_ref1 */      p++; break;
1118             case 0x12: /* FORM_ref2 */      p += 2; break;
1119             case 0x13: /* FORM_ref4 */      p += 4; break;
1120             case 0x14: /* FORM_ref8 */      p += 8; break;
1121             case 0x15: /* FORM_ref_udata */ read_leb128U( &p ); break;
1122             case 0x18: /* FORM_exprloc */   p += read_leb128U( &p ); break;
1123             case 0x19: /* FORM_flag_present */break;
1124             case 0x20: /* FORM_ref_sig8 */  p += 8; break;
1125 
1126             default:
1127                VG_(printf)( "### unhandled dwarf2 abbrev form code 0x%x\n", form );
1128                break;
1129          }
1130 
1131          /* Now store the members we need in the UnitInfo structure */
1132          if ( tag == 0x0011 /*TAG_compile_unit*/ ) {
1133                  if ( name == 0x03 ) ui->name = sval;      /* DW_AT_name */
1134             else if ( name == 0x1b ) ui->compdir = sval;   /* DW_AT_compdir */
1135             else if ( name == 0x10 ) ui->stmt_list = cval; /* DW_AT_stmt_list */
1136          }
1137       }
1138       /* Shortcut the parsing once we have read the compile_unit block
1139        * That's enough info for us, and we are not gdb ! */
1140       if ( tag == 0x0011 /*TAG_compile_unit*/ )
1141          break;
1142    } /* Loop on each sub block */
1143 
1144    /* This test would be valid if we were not shortcutting the parsing
1145    if (level != 0)
1146       VG_(printf)( "#### Exiting debuginfo block at level %d !!!\n", level );
1147    */
1148 }
1149 
1150 
1151 ////////////////////////////////////////////////////////////////////
1152 ////////////////////////////////////////////////////////////////////
1153 
1154 /* Collect the debug info from DWARF3 debugging sections
1155  * of a given module.
1156  *
1157  * Inputs: given .debug_xxx sections
1158  * Output: update di to contain all the DWARF3 debug infos
1159  */
ML_(read_debuginfo_dwarf3)1160 void ML_(read_debuginfo_dwarf3)
1161         ( struct _DebugInfo* di,
1162           UChar* debug_info_img, Word debug_info_sz, /* .debug_info */
1163           UChar* debug_abbv_img, Word debug_abbv_sz, /* .debug_abbrev */
1164           UChar* debug_line_img, Word debug_line_sz, /* .debug_line */
1165           UChar* debug_str_img,  Word debug_str_sz ) /* .debug_str */
1166 {
1167    UnitInfo ui;
1168    UShort   ver;
1169    UChar*   block_img;
1170    UChar*   end1_img;
1171    ULong    blklen;
1172    Bool     blklen_is_64;
1173    Int      blklen_len;
1174 
1175    end1_img  = debug_info_img + debug_info_sz;
1176    blklen_len = 0;
1177 
1178    /* Make sure we at least have a header for the first block */
1179    if (debug_info_sz < 4) {
1180       ML_(symerr)( di, True,
1181                    "Last block truncated in .debug_info; ignoring" );
1182       return;
1183    }
1184 
1185    /* Iterate on all the blocks we find in .debug_info */
1186    for ( block_img = debug_info_img;
1187          block_img < end1_img - 4;
1188          block_img += blklen + blklen_len ) {
1189 
1190       /* Read the compilation unit header in .debug_info section - See
1191          p 70 */
1192       /* This block length */
1193       blklen     = read_initial_length_field( block_img, &blklen_is_64 );
1194       blklen_len = blklen_is_64 ? 12 : 4;
1195       if ( block_img + blklen + blklen_len > end1_img ) {
1196          ML_(symerr)( di, True,
1197                       "Last block truncated in .debug_info; ignoring" );
1198          return;
1199       }
1200 
1201       /* version should be 2 */
1202       ver = *((UShort*)( block_img + blklen_len ));
1203       if ( ver != 2 && ver != 3 && ver != 4 ) {
1204          ML_(symerr)( di, True,
1205                       "Ignoring non-Dwarf2/3/4 block in .debug_info" );
1206          continue;
1207       }
1208 
1209       /* Fill ui with offset in .debug_line and compdir */
1210       if (0)
1211          VG_(printf)( "Reading UnitInfo at 0x%lx.....\n",
1212                       block_img - debug_info_img + 0UL );
1213       read_unitinfo_dwarf2( &ui, block_img,
1214                                  debug_abbv_img, debug_str_img );
1215       if (0)
1216          VG_(printf)( "   => LINES=0x%llx    NAME=%s     DIR=%s\n",
1217                       ui.stmt_list, ui.name, ui.compdir );
1218 
1219       /* Ignore blocks with no .debug_line associated block */
1220       if ( ui.stmt_list == -1LL )
1221          continue;
1222 
1223       if (0)
1224          VG_(printf)("debug_line_sz %ld, ui.stmt_list %lld  %s\n",
1225                      debug_line_sz, ui.stmt_list, ui.name );
1226       /* Read the .debug_line block for this compile unit */
1227       read_dwarf2_lineblock(
1228          di, &ui, debug_line_img + ui.stmt_list,
1229                   debug_line_sz  - ui.stmt_list );
1230    }
1231 }
1232 
1233 
1234 ////////////////////////////////////////////////////////////////////
1235 ////////////////////////////////////////////////////////////////////
1236 
1237 /*------------------------------------------------------------*/
1238 /*--- Read DWARF1 format line number info.                 ---*/
1239 /*------------------------------------------------------------*/
1240 
1241 /* DWARF1 appears to be redundant, but nevertheless the Lahey Fortran
1242    compiler generates it.
1243 */
1244 
1245 /* The following three enums (dwarf_tag, dwarf_form, dwarf_attribute)
1246    are taken from the file include/elf/dwarf.h in the GNU gdb-6.0
1247    sources, which are Copyright 1992, 1993, 1995, 1999 Free Software
1248    Foundation, Inc and naturally licensed under the GNU General Public
1249    License version 2 or later.
1250 */
1251 
1252 /* Tag names and codes.  */
1253 
1254 enum dwarf_tag {
1255     TAG_padding			= 0x0000,
1256     TAG_array_type		= 0x0001,
1257     TAG_class_type		= 0x0002,
1258     TAG_entry_point		= 0x0003,
1259     TAG_enumeration_type	= 0x0004,
1260     TAG_formal_parameter	= 0x0005,
1261     TAG_global_subroutine	= 0x0006,
1262     TAG_global_variable		= 0x0007,
1263     				/* 0x0008 -- reserved */
1264 				/* 0x0009 -- reserved */
1265     TAG_label			= 0x000a,
1266     TAG_lexical_block		= 0x000b,
1267     TAG_local_variable		= 0x000c,
1268     TAG_member			= 0x000d,
1269 				/* 0x000e -- reserved */
1270     TAG_pointer_type		= 0x000f,
1271     TAG_reference_type		= 0x0010,
1272     TAG_compile_unit		= 0x0011,
1273     TAG_string_type		= 0x0012,
1274     TAG_structure_type		= 0x0013,
1275     TAG_subroutine		= 0x0014,
1276     TAG_subroutine_type		= 0x0015,
1277     TAG_typedef			= 0x0016,
1278     TAG_union_type		= 0x0017,
1279     TAG_unspecified_parameters	= 0x0018,
1280     TAG_variant			= 0x0019,
1281     TAG_common_block		= 0x001a,
1282     TAG_common_inclusion	= 0x001b,
1283     TAG_inheritance		= 0x001c,
1284     TAG_inlined_subroutine	= 0x001d,
1285     TAG_module			= 0x001e,
1286     TAG_ptr_to_member_type	= 0x001f,
1287     TAG_set_type		= 0x0020,
1288     TAG_subrange_type		= 0x0021,
1289     TAG_with_stmt		= 0x0022,
1290 
1291     /* GNU extensions */
1292 
1293     TAG_format_label		= 0x8000,  /* for FORTRAN 77 and Fortran 90 */
1294     TAG_namelist		= 0x8001,  /* For Fortran 90 */
1295     TAG_function_template	= 0x8002,  /* for C++ */
1296     TAG_class_template		= 0x8003   /* for C++ */
1297 };
1298 
1299 /* Form names and codes.  */
1300 
1301 enum dwarf_form {
1302     FORM_ADDR	= 0x1,
1303     FORM_REF	= 0x2,
1304     FORM_BLOCK2	= 0x3,
1305     FORM_BLOCK4	= 0x4,
1306     FORM_DATA2	= 0x5,
1307     FORM_DATA4	= 0x6,
1308     FORM_DATA8	= 0x7,
1309     FORM_STRING	= 0x8
1310 };
1311 
1312 /* Attribute names and codes.  */
1313 
1314 enum dwarf_attribute {
1315     AT_sibling			= (0x0010|FORM_REF),
1316     AT_location			= (0x0020|FORM_BLOCK2),
1317     AT_name			= (0x0030|FORM_STRING),
1318     AT_fund_type		= (0x0050|FORM_DATA2),
1319     AT_mod_fund_type		= (0x0060|FORM_BLOCK2),
1320     AT_user_def_type		= (0x0070|FORM_REF),
1321     AT_mod_u_d_type		= (0x0080|FORM_BLOCK2),
1322     AT_ordering			= (0x0090|FORM_DATA2),
1323     AT_subscr_data		= (0x00a0|FORM_BLOCK2),
1324     AT_byte_size		= (0x00b0|FORM_DATA4),
1325     AT_bit_offset		= (0x00c0|FORM_DATA2),
1326     AT_bit_size			= (0x00d0|FORM_DATA4),
1327 				/* (0x00e0|FORM_xxxx) -- reserved */
1328     AT_element_list		= (0x00f0|FORM_BLOCK4),
1329     AT_stmt_list		= (0x0100|FORM_DATA4),
1330     AT_low_pc			= (0x0110|FORM_ADDR),
1331     AT_high_pc			= (0x0120|FORM_ADDR),
1332     AT_language			= (0x0130|FORM_DATA4),
1333     AT_member			= (0x0140|FORM_REF),
1334     AT_discr			= (0x0150|FORM_REF),
1335     AT_discr_value		= (0x0160|FORM_BLOCK2),
1336 				/* (0x0170|FORM_xxxx) -- reserved */
1337 				/* (0x0180|FORM_xxxx) -- reserved */
1338     AT_string_length		= (0x0190|FORM_BLOCK2),
1339     AT_common_reference		= (0x01a0|FORM_REF),
1340     AT_comp_dir			= (0x01b0|FORM_STRING),
1341         AT_const_value_string	= (0x01c0|FORM_STRING),
1342         AT_const_value_data2	= (0x01c0|FORM_DATA2),
1343         AT_const_value_data4	= (0x01c0|FORM_DATA4),
1344         AT_const_value_data8	= (0x01c0|FORM_DATA8),
1345         AT_const_value_block2	= (0x01c0|FORM_BLOCK2),
1346         AT_const_value_block4	= (0x01c0|FORM_BLOCK4),
1347     AT_containing_type		= (0x01d0|FORM_REF),
1348         AT_default_value_addr	= (0x01e0|FORM_ADDR),
1349         AT_default_value_data2	= (0x01e0|FORM_DATA2),
1350         AT_default_value_data4	= (0x01e0|FORM_DATA4),
1351         AT_default_value_data8	= (0x01e0|FORM_DATA8),
1352         AT_default_value_string	= (0x01e0|FORM_STRING),
1353     AT_friends			= (0x01f0|FORM_BLOCK2),
1354     AT_inline			= (0x0200|FORM_STRING),
1355     AT_is_optional		= (0x0210|FORM_STRING),
1356         AT_lower_bound_ref	= (0x0220|FORM_REF),
1357         AT_lower_bound_data2	= (0x0220|FORM_DATA2),
1358         AT_lower_bound_data4	= (0x0220|FORM_DATA4),
1359         AT_lower_bound_data8	= (0x0220|FORM_DATA8),
1360     AT_private			= (0x0240|FORM_STRING),
1361     AT_producer			= (0x0250|FORM_STRING),
1362     AT_program			= (0x0230|FORM_STRING),
1363     AT_protected		= (0x0260|FORM_STRING),
1364     AT_prototyped		= (0x0270|FORM_STRING),
1365     AT_public			= (0x0280|FORM_STRING),
1366     AT_pure_virtual		= (0x0290|FORM_STRING),
1367     AT_return_addr		= (0x02a0|FORM_BLOCK2),
1368     AT_abstract_origin		= (0x02b0|FORM_REF),
1369     AT_start_scope		= (0x02c0|FORM_DATA4),
1370     AT_stride_size		= (0x02e0|FORM_DATA4),
1371         AT_upper_bound_ref	= (0x02f0|FORM_REF),
1372         AT_upper_bound_data2	= (0x02f0|FORM_DATA2),
1373         AT_upper_bound_data4	= (0x02f0|FORM_DATA4),
1374         AT_upper_bound_data8	= (0x02f0|FORM_DATA8),
1375     AT_virtual			= (0x0300|FORM_STRING),
1376 
1377     /* GNU extensions.  */
1378 
1379     AT_sf_names			= (0x8000|FORM_DATA4),
1380     AT_src_info			= (0x8010|FORM_DATA4),
1381     AT_mac_info			= (0x8020|FORM_DATA4),
1382     AT_src_coords		= (0x8030|FORM_DATA4),
1383     AT_body_begin		= (0x8040|FORM_ADDR),
1384     AT_body_end			= (0x8050|FORM_ADDR)
1385 };
1386 
1387 /* end of enums taken from gdb-6.0 sources */
1388 
ML_(read_debuginfo_dwarf1)1389 void ML_(read_debuginfo_dwarf1) (
1390         struct _DebugInfo* di,
1391         UChar* dwarf1d, Int dwarf1d_sz,
1392         UChar* dwarf1l, Int dwarf1l_sz )
1393 {
1394    UInt   stmt_list;
1395    Bool   stmt_list_found;
1396    Int    die_offset, die_szb, at_offset;
1397    UShort die_kind, at_kind;
1398    UChar* at_base;
1399    UChar* src_filename;
1400 
1401    if (0)
1402       VG_(printf)("read_debuginfo_dwarf1 ( %p, %d, %p, %d )\n",
1403 	          dwarf1d, dwarf1d_sz, dwarf1l, dwarf1l_sz );
1404 
1405    /* This loop scans the DIEs. */
1406    die_offset = 0;
1407    while (True) {
1408       if (die_offset >= dwarf1d_sz) break;
1409 
1410       die_szb  = *(Int*)(dwarf1d + die_offset);
1411       die_kind = *(UShort*)(dwarf1d + die_offset + 4);
1412 
1413       /* We're only interested in compile_unit DIEs; ignore others. */
1414       if (die_kind != TAG_compile_unit) {
1415          die_offset += die_szb;
1416          continue;
1417       }
1418 
1419       if (0)
1420          VG_(printf)("compile-unit DIE: offset %d, tag 0x%x, size %d\n",
1421                      die_offset, (Int)die_kind, die_szb );
1422 
1423       /* We've got a compile_unit DIE starting at (dwarf1d +
1424          die_offset+6).  Try and find the AT_name and AT_stmt_list
1425          attributes.  Then, finally, we can read the line number info
1426          for this source file. */
1427 
1428       /* The next 3 are set as we find the relevant attrs. */
1429       src_filename    = NULL;
1430       stmt_list_found = False;
1431       stmt_list       = 0;
1432 
1433       /* This loop scans the Attrs inside compile_unit DIEs. */
1434       at_base = dwarf1d + die_offset + 6;
1435       at_offset = 0;
1436       while (True) {
1437          if (at_offset >= die_szb-6) break;
1438 
1439          at_kind = *(UShort*)(at_base + at_offset);
1440          if (0) VG_(printf)("atoffset %d, attag 0x%x\n",
1441                             at_offset, (Int)at_kind );
1442          at_offset += 2; /* step over the attribute itself */
1443 	 /* We have to examine the attribute to figure out its
1444             length. */
1445          switch (at_kind) {
1446             case AT_stmt_list:
1447             case AT_language:
1448             case AT_sibling:
1449                if (at_kind == AT_stmt_list) {
1450                   stmt_list_found = True;
1451                   stmt_list = *(Int*)(at_base+at_offset);
1452                }
1453                at_offset += 4; break;
1454             case AT_high_pc:
1455             case AT_low_pc:
1456                at_offset += sizeof(void*); break;
1457             case AT_name:
1458             case AT_producer:
1459             case AT_comp_dir:
1460                /* Zero terminated string, step over it. */
1461                if (at_kind == AT_name)
1462                   src_filename = at_base + at_offset;
1463                while (at_offset < die_szb-6 && at_base[at_offset] != 0)
1464                   at_offset++;
1465                at_offset++;
1466                break;
1467             default:
1468                VG_(printf)("Unhandled DWARF-1 attribute 0x%x\n",
1469                            (Int)at_kind );
1470                VG_(core_panic)("Unhandled DWARF-1 attribute");
1471          } /* switch (at_kind) */
1472       } /* looping over attributes */
1473 
1474       /* So, did we find the required stuff for a line number table in
1475          this DIE?  If yes, read it. */
1476       if (stmt_list_found /* there is a line number table */
1477           && src_filename != NULL /* we know the source filename */
1478          ) {
1479          /* Table starts:
1480                Length:
1481                   4 bytes, includes the entire table
1482                Base address:
1483                   unclear (4? 8?), assuming native pointer size here.
1484             Then a sequence of triples
1485                (source line number -- 32 bits
1486                 source line column -- 16 bits
1487                 address delta -- 32 bits)
1488 	 */
1489          Addr   base;
1490 	 Int    len;
1491          Char*  curr_filenm;
1492          UChar* ptr;
1493          UInt   prev_line, prev_delta;
1494 
1495          curr_filenm = ML_(addStr) ( di, src_filename, -1 );
1496          prev_line = prev_delta = 0;
1497 
1498          ptr = dwarf1l + stmt_list;
1499          len  =        *(Int*)ptr;    ptr += sizeof(Int);
1500          base = (Addr)(*(void**)ptr); ptr += sizeof(void*);
1501          len -= (sizeof(Int) + sizeof(void*));
1502          while (len > 0) {
1503             UInt   line;
1504             UShort col;
1505             UInt   delta;
1506             line = *(UInt*)ptr;  ptr += sizeof(UInt);
1507             col = *(UShort*)ptr;  ptr += sizeof(UShort);
1508             delta = *(UShort*)ptr;  ptr += sizeof(UInt);
1509 	    if (0) VG_(printf)("line %d, col %d, delta %d\n",
1510                                line, (Int)col, delta );
1511             len -= (sizeof(UInt) + sizeof(UShort) + sizeof(UInt));
1512 
1513 	    if (delta > 0 && prev_line > 0) {
1514 	       if (0) VG_(printf) ("     %d  %d-%d\n",
1515                                    prev_line, prev_delta, delta-1);
1516 	       ML_(addLineInfo) ( di, curr_filenm, NULL,
1517 		 	          base + prev_delta, base + delta,
1518 			          prev_line, 0 );
1519 	    }
1520 	    prev_line = line;
1521 	    prev_delta = delta;
1522 	 }
1523       }
1524 
1525       /* Move on the the next DIE. */
1526       die_offset += die_szb;
1527 
1528    } /* Looping over DIEs */
1529 
1530 }
1531 
1532 
1533 /*------------------------------------------------------------*/
1534 /*--- Read call-frame info from an .eh_frame section       ---*/
1535 /*------------------------------------------------------------*/
1536 
1537 /* Sources of info:
1538 
1539    The DWARF3 spec, available from http://www.dwarfstd.org/Download.php
1540 
1541    This describes how to read CFA data from .debug_frame sections.
1542    So as to maximise everybody's annoyance and confusion, .eh_frame
1543    sections are almost the same as .debug_frame sections, but differ
1544    in a few subtle and ill documented but important aspects.
1545 
1546    Generic ELF Specification, sections 7.5 (DWARF Extensions) and 7.6
1547    (Exception Frames), available from
1548 
1549    http://www.linux-foundation.org/spec/book/ELF-generic/ELF-generic.html
1550 
1551    This really does describe .eh_frame, at least the aspects that
1552    differ from standard DWARF3.  It's better than guessing, and
1553    (marginally) more fun than reading the gdb source code.
1554 */
1555 
1556 /* Useful info ..
1557 
1558    In general:
1559    gdb-6.3/gdb/dwarf2-frame.c
1560 
1561    gdb-6.3/gdb/i386-tdep.c:
1562 
1563    DWARF2/GCC uses the stack address *before* the function call as a
1564    frame's CFA.  [jrs: I presume this means %esp before the call as
1565    the CFA].
1566 
1567    JRS: on amd64, the dwarf register numbering is, as per
1568    gdb-6.3/gdb/amd64-tdep.c and also amd64-abi-0.98.pdf:
1569 
1570       0    1    2    3    4    5    6    7
1571       RAX  RDX  RCX  RBX  RSI  RDI  RBP  RSP
1572 
1573       8  ...  15
1574       R8 ... R15
1575 
1576       16 is the return address (RIP)
1577       "The table defines Return Address to have a register number,
1578       even though the address is stored in 0(%rsp) and not in a
1579       physical register."
1580 
1581       17   ...   24
1582       XMM0 ... XMM7
1583 
1584       25   ...    32
1585       XMM8 ... XMM15
1586 
1587       33   ...   40
1588       ST0  ...  ST7
1589 
1590       41   ...   48
1591       MM0  ...  MM7
1592 
1593       49                  RFLAGS
1594       50,51,52,53,54,55   ES,CS,SS,DS,FS,GS
1595       58                  FS.BASE  (what's that?)
1596       59                  GS.BASE  (what's that?)
1597       62                  TR (task register)
1598       63                  LDTR (LDT register)
1599       64                  MXCSR
1600       65                  FCW (x87 control word)
1601       66                  FSW (x86 status word)
1602 
1603    On x86 I cannot find any documentation.  It _appears_ to be the
1604    actual instruction encoding, viz:
1605 
1606       0    1    2    3    4    5    6    7
1607       EAX  ECX  EDX  EBX  ESP  EBP  ESI  EDI
1608 
1609       8 is the return address (EIP) */
1610 
1611 
1612 /* Comments re DW_CFA_set_loc, 16 Nov 06.
1613 
1614    JRS:
1615    Someone recently sent me a libcrypto.so.0.9.8 as distributed with
1616    Ubuntu of some flavour, compiled with gcc 4.1.2 on amd64.  It
1617    causes V's CF reader to complain a lot:
1618 
1619    >> --19976-- DWARF2 CFI reader: unhandled CFI instruction 0:24
1620    >> --19976-- DWARF2 CFI reader: unhandled CFI instruction 0:24
1621    >> --19976-- DWARF2 CFI reader: unhandled CFI instruction 0:24
1622    >> --19976-- DWARF2 CFI reader: unhandled CFI instruction 0:24
1623    >> --19976-- DWARF2 CFI reader: unhandled CFI instruction 0:48
1624    >> --19976-- DWARF2 CFI reader: unhandled CFI instruction 0:24
1625 
1626    After chasing this around a bit it seems that the CF bytecode
1627    parser lost sync at a DW_CFA_set_loc, which has a single argument
1628    denoting an address.
1629 
1630    As it stands that address is extracted by read_Addr().  On amd64
1631    that just fetches 8 bytes regardless of anything else.
1632 
1633    read_encoded_Addr() is more sophisticated.  This appears to take
1634    into account some kind of encoding flag.  When I replace the uses
1635    of read_Addr by read_encoded_Addr for DW_CFA_set_loc, the
1636    complaints go away, there is no loss of sync, and the parsed CF
1637    instructions are the same as shown by readelf --debug-dump=frames.
1638 
1639    So it seems a plausible fix.  The problem is I looked in the DWARF3
1640    spec and completely failed to figure out whether or not the arg to
1641    DW_CFA_set_loc is supposed to be encoded in a way suitable for
1642    read_encoded_Addr, nor for that matter any description of what it
1643    is that read_encoded_Addr is really decoding.
1644 
1645    TomH:
1646    The problem is that the encoding is not standard - the eh_frame
1647    section uses the same encoding as the dwarf_frame section except
1648    for a few small changes, and this is one of them. So this is not
1649    something the DWARF standard covers.
1650 
1651    There is an augmentation string to indicate what is going on though
1652    so that programs can recognise it.
1653 
1654    What we are doing seems to match what gdb 6.5 and libdwarf 20060614
1655    do though. I'm not sure about readelf though.
1656 
1657    (later): Well dwarfdump barfs on it:
1658 
1659       dwarfdump ERROR:  dwarf_get_fde_info_for_reg:
1660                         DW_DLE_DF_FRAME_DECODING_ERROR(193) (193)
1661 
1662    I've looked at binutils as well now, and the code in readelf agrees
1663    with your patch - ie it treats set_loc as having an encoded address
1664    if there is a zR augmentation indicating an encoding.
1665 
1666    Quite why gdb and libdwarf don't understand this is an interesting
1667    question...
1668 
1669    Final outcome: all uses of read_Addr were replaced by
1670    read_encoded_Addr.  A new type AddressDecodingInfo was added to
1671    make it relatively clean to plumb through the extra info needed by
1672    read_encoded_Addr.
1673 */
1674 
1675 /* More badness re address encoding, 12 Jan 07.
1676 
1677    Most gcc provided CIEs have a "zR" augmentation, which means they
1678    supply their own address encoding, and that works fine.  However,
1679    some icc9 supplied CIEs have no augmentation, which means they use
1680    the default_Addr_encoding().  That says to use a machine-word sized
1681    value, literally unmodified.
1682 
1683    Since .so's are, in general, relocated when loaded, having absolute
1684    addresses in the CFI data makes no sense when read_encoded_Addr is
1685    used to find the initial location for a FDE.  The resulting saga:
1686 
1687    TomH:
1688    > I'm chasing a stack backtrace failure for an amd64 .so which was
1689    > created I believe by icc 9.1.  After a while I wound up looking at
1690    > this: (readdwarf.c)
1691    >
1692    >   5083        tom static UChar default_Addr_encoding ( void )
1693    >   3584        tom {
1694    >   3584        tom    switch (sizeof(Addr)) {
1695    >   3584        tom       case 4: return DW_EH_PE_udata4;
1696    >   3584        tom       case 8: return DW_EH_PE_udata8;
1697    >   3584        tom       default: vg_assert(0);
1698    >   3584        tom    }
1699    >   3584        tom }
1700    >
1701    > If a CIE does not have an "augmentation string" (typically "zR") then
1702    > addresses are decoded as described by default_Addr_encoding.  If there
1703    > is an 'R' in the augmentation string then the encoding to use
1704    > is specified by the CIE itself, which works fine with GCC compiled code
1705    > since that always appears to specify zR.
1706 
1707    Correct.
1708 
1709    > Problem is this .so has no augmentation string and so uses the
1710    > default encoding, viz DW_EH_PE_udata8.  That appears to mean
1711    > "read a 64 bit number" and use that as-is (for the starting value
1712    > of the program counter when running the CFA program).
1713 
1714    Strictly speaking the default is DW_EH_PE_absptr, but that amounts
1715    to either udata4 or udata8 depending on the platform's pointer size
1716    which is a shortcut I used.
1717 
1718    > For this .so that gives nonsense (very small) PCs which are later
1719    > rejected by the sanity check which ensures PC ranges fall inside
1720    > the mapped text segment.  It seems like the .so expects to have the
1721    > start VMA of the text segment added on.  This would correspond to
1722    >
1723    >   static UChar default_Addr_encoding ( void )
1724    >   {
1725    >      switch (sizeof(Addr)) {
1726    >         case 4: return DW_EH_PE_textrel + DW_EH_PE_udata4;
1727    >         case 8: return DW_EH_PE_textrel + DW_EH_PE_udata8;
1728    >         default: vg_assert(0);
1729    >      }
1730    >   }
1731 
1732    The problem you're seeing is that you have absolute pointers inside
1733    a shared library, which obviously makes little sense on the face of
1734    things as how would the linker know where the library will be
1735    loaded?
1736 
1737    The answer of course is that it doesn't, so if it points absolute
1738    pointers in the frame unwind data is has to include relocations for
1739    them, and I'm betting that if you look at the relocations in the
1740    library you will there are some for that data.
1741 
1742    That is fine of course when ld.so maps the library - it will
1743    relocate the eh_frame data as it maps it (or prelinking will
1744    already have done so) and when the g++ exception code kicks in and
1745    unwinds the stack it will see relocated data.
1746 
1747    We of course are mapping the section from the ELF file ourselves
1748    and are not applying the relocations, hence the problem you are
1749    seeing.
1750 
1751    Strictly speaking we should apply the relocations but the cheap
1752    solution is essentially to do what you've done - strictly speaking
1753    you should adjust by the difference between the address the library
1754    was linked for and the address it has been loaded at, but a shared
1755    library will normally be linked for address zero I believe. It's
1756    possible that prelinking might change that though?
1757 
1758    JRS:
1759    That all syncs with what I am seeing.
1760 
1761    So what I am inclined to do is:
1762 
1763    - Leave default_Addr_encoding as it is
1764 
1765    - Change read_encoded_Addr's handling of "case DW_EH_PE_absptr" so
1766      it sets base to, as you say, the difference between the address
1767      the library was linked for and the address it has been loaded at
1768      (== the SegInfo's text_bias)
1769 
1770    Does that sound sane?  I think it should even handle the prelinked
1771    case.
1772 
1773    (JRS, later)
1774 
1775    Hmm.  Plausible as it sounds, it doesn't work.  It now produces
1776    bogus backtraces for locations inside the (statically linked)
1777    memcheck executable.
1778 
1779    Besides, there are a couple of other places where read_encoded_Addr
1780    is used -- one of which is used to establish the length of the
1781    address range covered by the current FDE:
1782 
1783          fde_arange = read_encoded_Addr(&nbytes, &adi, data);
1784 
1785    and it doesn't seem to make any sense for read_encoded_Addr to add
1786    on the text segment bias in that context.  The DWARF3 spec says
1787    that both the initial_location and address_range (length) fields
1788    are encoded the same way ("target address"), so it is unclear at
1789    what stage in the process it would be appropriate to relocate the
1790    former but not the latter.
1791 
1792    One unprincipled kludge that does work is the following: just
1793    before handing one of the address range fragments off to
1794    ML_(addDiCfSI) for permanent storage, check its start address.  If
1795    that is very low (less than 2 M), and is far below the mapped text
1796    segment, and adding the text bias would move the fragment entirely
1797    inside the mapped text segment, then do so.  A kind of kludged
1798    last-minute relocation, if you like.
1799 
1800    12 Jan 07: committing said kludge (see kludge_then_addDiCfSI).  If
1801    the situation clarifies, it can easily enough be backed out and
1802    replaced by a better fix.
1803 */
1804 
1805 /* --------------- Decls --------------- */
1806 
1807 #if defined(VGP_x86_linux)
1808 #  define FP_REG         5
1809 #  define SP_REG         4
1810 #  define RA_REG_DEFAULT 8
1811 #elif defined(VGP_amd64_linux)
1812 #  define FP_REG         6
1813 #  define SP_REG         7
1814 #  define RA_REG_DEFAULT 16
1815 #elif defined(VGP_ppc32_linux)
1816 #  define FP_REG         1
1817 #  define SP_REG         1
1818 #  define RA_REG_DEFAULT 65
1819 #elif defined(VGP_ppc64_linux)
1820 #  define FP_REG         1
1821 #  define SP_REG         1
1822 #  define RA_REG_DEFAULT 65
1823 #elif defined(VGP_arm_linux)
1824 #  define FP_REG         12
1825 #  define SP_REG         13
1826 #  define RA_REG_DEFAULT 14    //???
1827 #elif defined(VGP_x86_darwin)
1828 #  define FP_REG         5
1829 #  define SP_REG         4
1830 #  define RA_REG_DEFAULT 8
1831 #elif defined(VGP_amd64_darwin)
1832 #  define FP_REG         6
1833 #  define SP_REG         7
1834 #  define RA_REG_DEFAULT 16
1835 #else
1836 #  error "Unknown platform"
1837 #endif
1838 
1839 /* the number of regs we are prepared to unwind */
1840 #if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
1841 # define N_CFI_REGS 72
1842 #elif defined (VGP_arm_linux)
1843 /* 287 is the highest allocated DWARF register name as of 27.07.2011
1844   http://infocenter.arm.com/help/topic/com.arm.doc.ihi0040a/IHI0040A_aadwarf.pdf
1845 */
1846 # define N_CFI_REGS 287
1847 #else
1848 # define N_CFI_REGS 20
1849 #endif
1850 
1851 /* Instructions for the automaton */
1852 enum dwarf_cfa_primary_ops
1853   {
1854     DW_CFA_use_secondary = 0,
1855     DW_CFA_advance_loc   = 1,
1856     DW_CFA_offset        = 2,
1857     DW_CFA_restore       = 3
1858   };
1859 
1860 enum dwarf_cfa_secondary_ops
1861   {
1862     DW_CFA_nop                = 0x00,
1863     DW_CFA_set_loc            = 0x01,
1864     DW_CFA_advance_loc1       = 0x02,
1865     DW_CFA_advance_loc2       = 0x03,
1866     DW_CFA_advance_loc4       = 0x04,
1867     DW_CFA_offset_extended    = 0x05,
1868     DW_CFA_restore_extended   = 0x06,
1869     DW_CFA_undefined          = 0x07,
1870     DW_CFA_same_value         = 0x08,
1871     DW_CFA_register           = 0x09,
1872     DW_CFA_remember_state     = 0x0a,
1873     DW_CFA_restore_state      = 0x0b,
1874     DW_CFA_def_cfa            = 0x0c,
1875     DW_CFA_def_cfa_register   = 0x0d,
1876     DW_CFA_def_cfa_offset     = 0x0e,
1877     DW_CFA_def_cfa_expression = 0x0f, /* DWARF3 only */
1878     DW_CFA_expression         = 0x10, /* DWARF3 only */
1879     DW_CFA_offset_extended_sf = 0x11, /* DWARF3 only */
1880     DW_CFA_def_cfa_sf         = 0x12, /* DWARF3 only */
1881     DW_CFA_def_cfa_offset_sf  = 0x13, /* DWARF3 only */
1882     DW_CFA_val_offset         = 0x14, /* DWARF3 only */
1883     DW_CFA_val_offset_sf      = 0x15, /* DWARF3 only */
1884     DW_CFA_val_expression     = 0x16, /* DWARF3 only */
1885     DW_CFA_lo_user            = 0x1c,
1886     DW_CFA_GNU_window_save    = 0x2d, /* GNU extension */
1887     DW_CFA_GNU_args_size      = 0x2e, /* GNU extension */
1888     DW_CFA_GNU_negative_offset_extended = 0x2f, /* GNU extension */
1889     DW_CFA_hi_user            = 0x3f
1890   };
1891 
1892 #define DW_EH_PE_absptr		0x00
1893 #define DW_EH_PE_omit		0xff
1894 
1895 #define DW_EH_PE_uleb128	0x01
1896 #define DW_EH_PE_udata2		0x02
1897 #define DW_EH_PE_udata4		0x03
1898 #define DW_EH_PE_udata8		0x04
1899 #define DW_EH_PE_sleb128	0x09
1900 #define DW_EH_PE_sdata2		0x0A
1901 #define DW_EH_PE_sdata4		0x0B
1902 #define DW_EH_PE_sdata8		0x0C
1903 #define DW_EH_PE_signed		0x08
1904 
1905 #define DW_EH_PE_pcrel		0x10
1906 #define DW_EH_PE_textrel	0x20
1907 #define DW_EH_PE_datarel	0x30
1908 #define DW_EH_PE_funcrel	0x40
1909 #define DW_EH_PE_aligned	0x50
1910 
1911 #define DW_EH_PE_indirect	0x80
1912 
1913 
1914 /* RegRule and UnwindContext are used temporarily to do the unwinding.
1915    The result is then summarised into a sequence of CfiSIs, if
1916    possible.  UnwindContext effectively holds the state of the
1917    abstract machine whilst it is running.
1918 
1919    The CFA can either be a signed offset from a register,
1920    or an expression:
1921 
1922    CFA = cfa_reg + cfa_off   when UnwindContext.cfa_is_regoff==True
1923        | [[ cfa_expr_id ]]
1924 
1925    When .cfa_is_regoff == True,  cfa_expr_id must be zero
1926    When .cfa_is_regoff == False, cfa_reg must be zero
1927                                  and cfa_off must be zero
1928 
1929    RegRule describes, for each register, how to get its
1930    value in the previous frame, where 'cfa' denotes the cfa
1931    for the frame as a whole:
1932 
1933    RegRule = RR_Undef          -- undefined
1934            | RR_Same           -- same as in previous frame
1935            | RR_CFAOff    arg  -- is at * ( cfa + arg )
1936            | RR_CFAValOff arg  -- is ( cfa + arg )
1937            | RR_Reg       arg  -- is in register 'arg'
1938            | RR_Expr      arg  -- is at * [[ arg ]]
1939            | RR_ValExpr   arg  -- is [[ arg ]]
1940            | RR_Arch           -- dunno
1941 
1942    Note that RR_Expr is redundant since the same can be represented
1943    using RR_ValExpr with an explicit dereference (CfiExpr_Deref) at
1944    the outermost level.
1945 
1946    All expressions are stored in exprs in the containing
1947    UnwindContext.  Since the UnwindContext gets reinitialised for each
1948    new FDE, summarise_context needs to copy out any expressions it
1949    wants to keep into the cfsi_exprs field of the containing SegInfo.
1950 */
1951 typedef
1952    struct {
1953       enum { RR_Undef, RR_Same, RR_CFAOff, RR_CFAValOff,
1954              RR_Reg, /*RR_Expr,*/ RR_ValExpr, RR_Arch } tag;
1955       /* meaning:  int offset for CFAoff/CFAValOff
1956                    reg # for Reg
1957                    expr index for Expr/ValExpr */
1958       Int arg;
1959    }
1960    RegRule;
1961 
ppRegRule(XArray * exprs,RegRule * rrule)1962 static void ppRegRule ( XArray* exprs, RegRule* rrule )
1963 {
1964    vg_assert(exprs);
1965    switch (rrule->tag) {
1966       case RR_Undef:     VG_(printf)("u  "); break;
1967       case RR_Same:      VG_(printf)("s  "); break;
1968       case RR_CFAOff:    VG_(printf)("c%d ", rrule->arg); break;
1969       case RR_CFAValOff: VG_(printf)("v%d ", rrule->arg); break;
1970       case RR_Reg:       VG_(printf)("r%d ", rrule->arg); break;
1971       case RR_ValExpr:   VG_(printf)("ve{");
1972                          ML_(ppCfiExpr)( exprs, rrule->arg );
1973                          VG_(printf)("} ");
1974                          break;
1975       case RR_Arch:      VG_(printf)("a  "); break;
1976       default:           VG_(core_panic)("ppRegRule");
1977    }
1978 }
1979 
1980 
1981 /* Size of the stack of register unwind rules.  This is only
1982    exceedingly rarely used, so a stack of size 1 should actually work
1983    with almost all compiler-generated CFA. */
1984 #define N_RR_STACK 4
1985 
1986 typedef
1987    struct {
1988       /* Read-only fields (set by the CIE) */
1989       Int     code_a_f;
1990       Int     data_a_f;
1991       Addr    initloc;
1992       Int     ra_reg;
1993       /* The rest of these fields can be modifed by
1994          run_CF_instruction. */
1995       /* The LOC entry */
1996       Addr    loc;
1997       /* We need a stack of these in order to handle
1998          DW_CFA_{remember,restore}_state. */
1999       struct UnwindContextState {
2000           /* The CFA entry.  This can be either reg+/-offset or an expr. */
2001           Bool    cfa_is_regoff; /* True=>is reg+offset; False=>is expr */
2002           Int     cfa_reg;
2003           Int     cfa_off;  /* in bytes */
2004           Int     cfa_expr_ix; /* index into cfa_exprs */
2005           /* Register unwind rules.  */
2006           RegRule reg[N_CFI_REGS];
2007       }
2008       state[N_RR_STACK];
2009       Int     state_sp; /* 0 <= state_sp < N_RR_STACK; points at the
2010                            currently-in-use rule set. */
2011       /* array of CfiExpr, shared by reg[] and cfa_expr_ix */
2012       XArray* exprs;
2013    }
2014    UnwindContext;
2015 
ppUnwindContext(UnwindContext * ctx)2016 static void ppUnwindContext ( UnwindContext* ctx )
2017 {
2018    Int j, i;
2019    VG_(printf)("0x%llx: ", (ULong)ctx->loc);
2020    for (j = 0; j <= ctx->state_sp; j++) {
2021       struct UnwindContextState* ctxs = &ctx->state[j];
2022       VG_(printf)("%s[%d]={ ", j > 0 ? " " : "", j);
2023       if (ctxs->cfa_is_regoff) {
2024          VG_(printf)("%d(r%d) ", ctxs->cfa_off, ctxs->cfa_reg);
2025       } else {
2026          vg_assert(ctx->exprs);
2027          VG_(printf)("{");
2028          ML_(ppCfiExpr)( ctx->exprs, ctxs->cfa_expr_ix );
2029          VG_(printf)("} ");
2030       }
2031       VG_(printf)("{ ");
2032       for (i = 0; i < N_CFI_REGS; i++)
2033          ppRegRule(ctx->exprs, &ctxs->reg[i]);
2034       VG_(printf)("}");
2035    }
2036    VG_(printf)("\n");
2037 }
2038 
initUnwindContext(UnwindContext * ctx)2039 static void initUnwindContext ( /*OUT*/UnwindContext* ctx )
2040 {
2041    Int j, i;
2042    VG_(memset)(ctx, 0, sizeof(*ctx));
2043    /* ctx->code_a_f   = 0;
2044    ctx->data_a_f      = 0;
2045    ctx->initloc       = 0; */
2046    ctx->ra_reg        = RA_REG_DEFAULT;
2047    /* ctx->loc        = 0;
2048    ctx->exprs         = NULL;
2049    ctx->state_sp        = 0; */
2050    for (j = 0; j < N_RR_STACK; j++) {
2051       ctx->state[j].cfa_is_regoff = True;
2052       /* ctx->state[j].cfa_reg    = 0;
2053       ctx->state[j].cfa_off       = 0;
2054       ctx->state[j].cfa_expr_ix   = 0; */
2055       for (i = 0; i < N_CFI_REGS; i++) {
2056          if (RR_Undef != 0)
2057            ctx->state[j].reg[i].tag = RR_Undef;
2058          /* ctx->state[j].reg[i].arg = 0; */
2059       }
2060 #     if defined(VGA_arm)
2061       /* All callee-saved registers (or at least the ones we are
2062          summarising for) should start out as RR_Same, on ARM. */
2063       ctx->state[j].reg[11].tag = RR_Same;
2064       /* ctx->state[j].reg[13].tag = RR_Same; */
2065       ctx->state[j].reg[14].tag = RR_Same;
2066       ctx->state[j].reg[12].tag = RR_Same;
2067       ctx->state[j].reg[7].tag  = RR_Same;
2068       /* this can't be right though: R12 (IP) isn't callee saved. */
2069 #     endif
2070    }
2071 }
2072 
2073 
2074 /* A structure which holds information needed by read_encoded_Addr().
2075 */
2076 typedef
2077    struct {
2078       UChar  encoding;
2079       UChar* ehframe_image;
2080       Addr   ehframe_avma;
2081       Addr   text_bias;
2082    }
2083    AddressDecodingInfo;
2084 
2085 
2086 /* ------------ Deal with summary-info records ------------ */
2087 
initCfiSI(DiCfSI * si)2088 static void initCfiSI ( DiCfSI* si )
2089 {
2090    VG_(memset)(si, 0, sizeof(*si));
2091 }
2092 
2093 
2094 /* --------------- Summarisation --------------- */
2095 
2096 /* Forward */
2097 static
2098 Int copy_convert_CfiExpr_tree ( XArray*        dst,
2099                                 UnwindContext* srcuc,
2100                                 Int            nd );
2101 
2102 /* Summarise ctx into si, if possible.  Returns True if successful.
2103    This is taken to be just after ctx's loc advances; hence the
2104    summary is up to but not including the current loc.  This works
2105    on both x86 and amd64.
2106 */
summarise_context(DiCfSI * si,Addr loc_start,UnwindContext * ctx,struct _DebugInfo * debuginfo)2107 static Bool summarise_context( /*OUT*/DiCfSI* si,
2108                                Addr loc_start,
2109 	                       UnwindContext* ctx,
2110                                struct _DebugInfo* debuginfo )
2111 {
2112    Int why = 0;
2113    struct UnwindContextState* ctxs;
2114    initCfiSI(si);
2115 
2116    /* Guard against obviously stupid settings of the reg-rule stack
2117       pointer. */
2118    if (ctx->state_sp < 0)           { why = 8; goto failed; }
2119    if (ctx->state_sp >= N_RR_STACK) { why = 9; goto failed; }
2120    ctxs = &ctx->state[ctx->state_sp];
2121 
2122    /* First, summarise the method for generating the CFA */
2123    if (!ctxs->cfa_is_regoff) {
2124       /* it was set by DW_CFA_def_cfa_expression; try to convert */
2125       XArray *src, *dst;
2126       Int    conv;
2127       src = ctx->exprs;
2128       dst = debuginfo->cfsi_exprs;
2129       if (src && (VG_(sizeXA)(src) > 0) && (!dst)) {
2130          dst = VG_(newXA)( ML_(dinfo_zalloc), "di.ccCt.1", ML_(dinfo_free),
2131                            sizeof(CfiExpr) );
2132          vg_assert(dst);
2133          debuginfo->cfsi_exprs = dst;
2134       }
2135       conv = copy_convert_CfiExpr_tree
2136                     ( dst, ctx, ctxs->cfa_expr_ix );
2137       vg_assert(conv >= -1);
2138       if (conv == -1) { why = 6; goto failed; }
2139       si->cfa_how = CFIC_EXPR;
2140       si->cfa_off = conv;
2141       if (0 && debuginfo->ddump_frames)
2142          ML_(ppCfiExpr)(dst, conv);
2143    }
2144    else
2145    if (ctxs->cfa_is_regoff && ctxs->cfa_reg == SP_REG) {
2146       si->cfa_off = ctxs->cfa_off;
2147 #     if defined(VGA_x86) || defined(VGA_amd64)
2148       si->cfa_how = CFIC_IA_SPREL;
2149 #     elif defined(VGA_arm)
2150       si->cfa_how = CFIC_ARM_R13REL;
2151 #     else
2152       si->cfa_how = 0; /* invalid */
2153 #     endif
2154    }
2155    else
2156    if (ctxs->cfa_is_regoff && ctxs->cfa_reg == FP_REG) {
2157       si->cfa_off = ctxs->cfa_off;
2158 #     if defined(VGA_x86) || defined(VGA_amd64)
2159       si->cfa_how = CFIC_IA_BPREL;
2160 #     elif defined(VGA_arm)
2161       si->cfa_how = CFIC_ARM_R12REL;
2162 #     else
2163       si->cfa_how = 0; /* invalid */
2164 #     endif
2165    }
2166 #  if defined(VGA_arm)
2167    else
2168    if (ctxs->cfa_is_regoff && ctxs->cfa_reg == 11/*??_REG*/) {
2169       si->cfa_how = CFIC_ARM_R11REL;
2170       si->cfa_off = ctxs->cfa_off;
2171    }
2172    else
2173    if (ctxs->cfa_is_regoff && ctxs->cfa_reg == 7/*??_REG*/) {
2174       si->cfa_how = CFIC_ARM_R7REL;
2175       si->cfa_off = ctxs->cfa_off;
2176    }
2177 #  endif
2178    else {
2179       why = 1;
2180       goto failed;
2181    }
2182 
2183 #  define SUMMARISE_HOW(_how, _off, _ctxreg)                  \
2184    switch (_ctxreg.tag) {                                     \
2185       case RR_Undef:                                          \
2186          _how = CFIR_UNKNOWN;   _off = 0; break;              \
2187       case RR_Same:                                           \
2188          _how = CFIR_SAME;      _off = 0; break;              \
2189       case RR_CFAOff:                                         \
2190          _how = CFIR_MEMCFAREL; _off = _ctxreg.arg; break;    \
2191       case RR_CFAValOff:                                      \
2192          _how = CFIR_CFAREL;    _off = _ctxreg.arg; break;    \
2193       case RR_ValExpr: {                                      \
2194          XArray *src, *dst;                                   \
2195          Int    conv;                                         \
2196          src = ctx->exprs;                                    \
2197          dst = debuginfo->cfsi_exprs;                         \
2198          if (src && (VG_(sizeXA)(src) > 0) && (!dst)) {       \
2199             dst = VG_(newXA)( ML_(dinfo_zalloc),              \
2200                               "di.ccCt.2",                    \
2201                               ML_(dinfo_free),                \
2202                               sizeof(CfiExpr) );              \
2203             vg_assert(dst);                                   \
2204             debuginfo->cfsi_exprs = dst;                      \
2205          }                                                    \
2206          conv = copy_convert_CfiExpr_tree                     \
2207                        ( dst, ctx, _ctxreg.arg );             \
2208          vg_assert(conv >= -1);                               \
2209          if (conv == -1) { why = 7; goto failed; }            \
2210          _how = CFIR_EXPR;                                    \
2211          _off = conv;                                         \
2212          if (0 && debuginfo->ddump_frames)                    \
2213             ML_(ppCfiExpr)(dst, conv);                        \
2214          break;                                               \
2215       }                                                       \
2216       default:                                                \
2217          why = 2; goto failed; /* otherwise give up */        \
2218    }
2219 
2220 #  if defined(VGA_x86) || defined(VGA_amd64)
2221 
2222    /* --- entire tail of this fn specialised for x86/amd64 --- */
2223 
2224    SUMMARISE_HOW(si->ra_how, si->ra_off,
2225                              ctxs->reg[ctx->ra_reg] );
2226    SUMMARISE_HOW(si->bp_how, si->bp_off,
2227                              ctxs->reg[FP_REG] );
2228 
2229    /* on x86/amd64, it seems the old %{e,r}sp value before the call is
2230       always the same as the CFA.  Therefore ... */
2231    si->sp_how = CFIR_CFAREL;
2232    si->sp_off = 0;
2233 
2234    /* also, gcc says "Undef" for %{e,r}bp when it is unchanged.  So
2235       .. */
2236    if (ctxs->reg[FP_REG].tag == RR_Undef)
2237       si->bp_how = CFIR_SAME;
2238 
2239    /* knock out some obviously stupid cases */
2240    if (si->ra_how == CFIR_SAME)
2241       { why = 3; goto failed; }
2242 
2243    /* bogus looking range?  Note, we require that the difference is
2244       representable in 32 bits. */
2245    if (loc_start >= ctx->loc)
2246       { why = 4; goto failed; }
2247    if (ctx->loc - loc_start > 10000000 /* let's say */)
2248       { why = 5; goto failed; }
2249 
2250    si->base = loc_start + ctx->initloc;
2251    si->len  = (UInt)(ctx->loc - loc_start);
2252 
2253    return True;
2254 
2255 #  elif defined(VGA_arm)
2256 
2257    /* ---- entire tail of this fn specialised for arm ---- */
2258 
2259    SUMMARISE_HOW(si->r14_how, si->r14_off,
2260                               ctxs->reg[14] );
2261 
2262    //SUMMARISE_HOW(si->r13_how, si->r13_off,
2263    //                           ctxs->reg[13] );
2264 
2265    SUMMARISE_HOW(si->r12_how, si->r12_off,
2266                               ctxs->reg[FP_REG] );
2267 
2268    SUMMARISE_HOW(si->r11_how, si->r11_off,
2269                               ctxs->reg[11/*FP_REG*/] );
2270 
2271    SUMMARISE_HOW(si->r7_how, si->r7_off,
2272                              ctxs->reg[7] );
2273 
2274    if (ctxs->reg[14/*LR*/].tag == RR_Same
2275        && ctx->ra_reg == 14/*as we expect it always to be*/) {
2276       /* Generate a trivial CfiExpr, which merely says "r14".  First
2277          ensure this DebugInfo has a cfsi_expr array in which to park
2278          it. */
2279       if (!debuginfo->cfsi_exprs)
2280          debuginfo->cfsi_exprs = VG_(newXA)( ML_(dinfo_zalloc),
2281                                              "di.ccCt.2a",
2282                                              ML_(dinfo_free),
2283                                              sizeof(CfiExpr) );
2284       si->ra_off = ML_(CfiExpr_CfiReg)( debuginfo->cfsi_exprs,
2285                                         Creg_ARM_R14);
2286       si->ra_how = CFIR_EXPR;
2287    } else {
2288       /* Just summarise it in the normal way */
2289       SUMMARISE_HOW(si->ra_how, si->ra_off,
2290                                 ctxs->reg[ctx->ra_reg] );
2291    }
2292 
2293    /* on arm, it seems the old r13 (SP) value before the call is
2294       always the same as the CFA.  Therefore ... */
2295    si->r13_how = CFIR_CFAREL;
2296    si->r13_off = 0;
2297 
2298    /* bogus looking range?  Note, we require that the difference is
2299       representable in 32 bits. */
2300    if (loc_start >= ctx->loc)
2301       { why = 4; goto failed; }
2302    if (ctx->loc - loc_start > 10000000 /* let's say */)
2303       { why = 5; goto failed; }
2304 
2305    si->base = loc_start + ctx->initloc;
2306    si->len  = (UInt)(ctx->loc - loc_start);
2307 
2308    return True;
2309 
2310 
2311 #  elif defined(VGA_ppc32) || defined(VGA_ppc64)
2312 #  else
2313 #    error "Unknown arch"
2314 #  endif
2315 
2316 #  undef SUMMARISE_HOW
2317 
2318   failed:
2319    if (VG_(clo_verbosity) > 2 || debuginfo->trace_cfi) {
2320       VG_(message)(Vg_DebugMsg,
2321                   "summarise_context(loc_start = %#lx)"
2322                   ": cannot summarise(why=%d):   \n", loc_start, why);
2323       ppUnwindContext(ctx);
2324    }
2325    return False;
2326 }
2327 
2328 /* Copy the tree rooted at srcuc->exprs node srcix to dstxa, on the
2329    way converting any DwReg regs (regs numbered using the Dwarf scheme
2330    defined by each architecture's ABI) into CfiRegs, which are
2331    platform independent.  If the conversion isn't possible because
2332    there is no equivalent register, return -1.  This has the
2333    undesirable side effect of de-dagifying the input; oh well. */
copy_convert_CfiExpr_tree(XArray * dstxa,UnwindContext * srcuc,Int srcix)2334 static Int copy_convert_CfiExpr_tree ( XArray*        dstxa,
2335                                        UnwindContext* srcuc,
2336                                        Int            srcix )
2337 {
2338    CfiExpr* src;
2339    Int      cpL, cpR, cpA, dwreg;
2340    XArray*  srcxa = srcuc->exprs;
2341    vg_assert(srcxa);
2342    vg_assert(dstxa);
2343    vg_assert(srcix >= 0 && srcix < VG_(sizeXA)(srcxa));
2344 
2345    src = VG_(indexXA)( srcxa, srcix );
2346    switch (src->tag) {
2347       case Cex_Undef:
2348          return ML_(CfiExpr_Undef)( dstxa );
2349       case Cex_Deref:
2350          cpA = copy_convert_CfiExpr_tree( dstxa, srcuc, src->Cex.Deref.ixAddr );
2351          if (cpA == -1)
2352             return -1; /* propagate failure */
2353          return ML_(CfiExpr_Deref)( dstxa, cpA );
2354       case Cex_Const:
2355          return ML_(CfiExpr_Const)( dstxa, src->Cex.Const.con );
2356       case Cex_Binop:
2357          cpL = copy_convert_CfiExpr_tree( dstxa, srcuc, src->Cex.Binop.ixL );
2358          cpR = copy_convert_CfiExpr_tree( dstxa, srcuc, src->Cex.Binop.ixR );
2359          vg_assert(cpL >= -1 && cpR >= -1);
2360          if (cpL == -1 || cpR == -1)
2361             return -1; /* propagate failure */
2362          return ML_(CfiExpr_Binop)( dstxa, src->Cex.Binop.op, cpL, cpR );
2363       case Cex_CfiReg:
2364          /* should not see these in input (are created only by this
2365             conversion step!) */
2366          VG_(core_panic)("copy_convert_CfiExpr_tree: CfiReg in input");
2367       case Cex_DwReg:
2368          /* This is the only place where the conversion can fail. */
2369          dwreg = src->Cex.DwReg.reg;
2370 #        if defined(VGA_x86) || defined(VGA_amd64)
2371          if (dwreg == SP_REG)
2372             return ML_(CfiExpr_CfiReg)( dstxa, Creg_IA_SP );
2373          if (dwreg == FP_REG)
2374             return ML_(CfiExpr_CfiReg)( dstxa, Creg_IA_BP );
2375          if (dwreg == srcuc->ra_reg)
2376             return ML_(CfiExpr_CfiReg)( dstxa, Creg_IA_IP ); /* correct? */
2377 #        elif defined(VGA_arm)
2378          if (dwreg == SP_REG)
2379             return ML_(CfiExpr_CfiReg)( dstxa, Creg_ARM_R13 );
2380          if (dwreg == FP_REG)
2381             return ML_(CfiExpr_CfiReg)( dstxa, Creg_ARM_R12 );
2382          if (dwreg == srcuc->ra_reg)
2383            return ML_(CfiExpr_CfiReg)( dstxa, Creg_ARM_R15 ); /* correct? */
2384 #        elif defined(VGA_ppc32) || defined(VGA_ppc64)
2385 #        else
2386 #           error "Unknown arch"
2387 #        endif
2388          /* else we must fail - can't represent the reg */
2389          return -1;
2390       default:
2391          VG_(core_panic)("copy_convert_CfiExpr_tree: default");
2392    }
2393 }
2394 
2395 
ppUnwindContext_summary(UnwindContext * ctx)2396 static void ppUnwindContext_summary ( UnwindContext* ctx )
2397 {
2398    struct UnwindContextState* ctxs = &ctx->state[ctx->state_sp];
2399 
2400    VG_(printf)("0x%llx-1: ", (ULong)ctx->loc);
2401 
2402    if (ctxs->cfa_reg == SP_REG) {
2403       VG_(printf)("SP/CFA=%d+SP   ", ctxs->cfa_off);
2404    } else
2405    if (ctxs->cfa_reg == FP_REG) {
2406       VG_(printf)("SP/CFA=%d+FP   ", ctxs->cfa_off);
2407    } else {
2408       VG_(printf)("SP/CFA=unknown  ");
2409    }
2410 
2411    VG_(printf)("RA=");
2412    ppRegRule( ctx->exprs, &ctxs->reg[ctx->ra_reg] );
2413 
2414    VG_(printf)("FP=");
2415    ppRegRule( ctx->exprs, &ctxs->reg[FP_REG] );
2416    VG_(printf)("\n");
2417 }
2418 
2419 
2420 /* ------------ Pick apart DWARF2 byte streams ------------ */
2421 
host_is_little_endian(void)2422 static inline Bool host_is_little_endian ( void )
2423 {
2424    UInt x = 0x76543210;
2425    UChar* p = (UChar*)(&x);
2426    return toBool(*p == 0x10);
2427 }
2428 
read_Short(UChar * data)2429 static Short read_Short ( UChar* data )
2430 {
2431    Short r = 0;
2432    if (host_is_little_endian()) {
2433       r = data[0]
2434           | ( ((UInt)data[1]) << 8 );
2435    } else {
2436       r = data[1]
2437           | ( ((UInt)data[0]) << 8 );
2438    }
2439    return r;
2440 }
2441 
read_Int(UChar * data)2442 static Int read_Int ( UChar* data )
2443 {
2444    Int r = 0;
2445    if (host_is_little_endian()) {
2446       r = data[0]
2447           | ( ((UInt)data[1]) << 8 )
2448           | ( ((UInt)data[2]) << 16 )
2449           | ( ((UInt)data[3]) << 24 );
2450    } else {
2451       r = data[3]
2452           | ( ((UInt)data[2]) << 8 )
2453           | ( ((UInt)data[1]) << 16 )
2454           | ( ((UInt)data[0]) << 24 );
2455    }
2456    return r;
2457 }
2458 
read_Long(UChar * data)2459 static Long read_Long ( UChar* data )
2460 {
2461    Long r = 0;
2462    if (host_is_little_endian()) {
2463       r = data[0]
2464           | ( ((ULong)data[1]) << 8 )
2465           | ( ((ULong)data[2]) << 16 )
2466           | ( ((ULong)data[3]) << 24 )
2467           | ( ((ULong)data[4]) << 32 )
2468           | ( ((ULong)data[5]) << 40 )
2469           | ( ((ULong)data[6]) << 48 )
2470           | ( ((ULong)data[7]) << 56 );
2471    } else {
2472       r = data[7]
2473           | ( ((ULong)data[6]) << 8 )
2474           | ( ((ULong)data[5]) << 16 )
2475           | ( ((ULong)data[4]) << 24 )
2476           | ( ((ULong)data[3]) << 32 )
2477           | ( ((ULong)data[2]) << 40 )
2478           | ( ((ULong)data[1]) << 48 )
2479           | ( ((ULong)data[0]) << 56 );
2480    }
2481    return r;
2482 }
2483 
read_UShort(UChar * data)2484 static UShort read_UShort ( UChar* data )
2485 {
2486    UInt r = 0;
2487    if (host_is_little_endian()) {
2488       r = data[0]
2489           | ( ((UInt)data[1]) << 8 );
2490    } else {
2491       r = data[1]
2492           | ( ((UInt)data[0]) << 8 );
2493    }
2494    return r;
2495 }
2496 
read_UInt(UChar * data)2497 static UInt read_UInt ( UChar* data )
2498 {
2499    UInt r = 0;
2500    if (host_is_little_endian()) {
2501       r = data[0]
2502           | ( ((UInt)data[1]) << 8 )
2503           | ( ((UInt)data[2]) << 16 )
2504           | ( ((UInt)data[3]) << 24 );
2505    } else {
2506       r = data[3]
2507           | ( ((UInt)data[2]) << 8 )
2508           | ( ((UInt)data[1]) << 16 )
2509           | ( ((UInt)data[0]) << 24 );
2510    }
2511    return r;
2512 }
2513 
read_ULong(UChar * data)2514 static ULong read_ULong ( UChar* data )
2515 {
2516    ULong r = 0;
2517    if (host_is_little_endian()) {
2518       r = data[0]
2519        | ( ((ULong)data[1]) << 8 )
2520        | ( ((ULong)data[2]) << 16 )
2521        | ( ((ULong)data[3]) << 24 )
2522        | ( ((ULong)data[4]) << 32 )
2523        | ( ((ULong)data[5]) << 40 )
2524        | ( ((ULong)data[6]) << 48 )
2525        | ( ((ULong)data[7]) << 56 );
2526    } else {
2527       r = data[7]
2528        | ( ((ULong)data[6]) << 8 )
2529        | ( ((ULong)data[5]) << 16 )
2530        | ( ((ULong)data[4]) << 24 )
2531        | ( ((ULong)data[3]) << 32 )
2532        | ( ((ULong)data[2]) << 40 )
2533        | ( ((ULong)data[1]) << 48 )
2534        | ( ((ULong)data[0]) << 56 );
2535    }
2536    return r;
2537 }
2538 
read_UChar(UChar * data)2539 static UChar read_UChar ( UChar* data )
2540 {
2541    return data[0];
2542 }
2543 
read_le_u_encoded_literal(UChar * data,UInt size)2544 static ULong read_le_u_encoded_literal ( UChar* data, UInt size )
2545 {
2546    switch (size) {
2547       case 8:  return (ULong)read_ULong( data );
2548       case 4:  return (ULong)read_UInt( data );
2549       case 2:  return (ULong)read_UShort( data );
2550       case 1:  return (ULong)read_UChar( data );
2551       default: vg_assert(0); /*NOTREACHED*/ return 0;
2552    }
2553 }
2554 
read_le_s_encoded_literal(UChar * data,UInt size)2555 static Long read_le_s_encoded_literal ( UChar* data, UInt size )
2556 {
2557    Long s64 = read_le_u_encoded_literal( data, size );
2558    switch (size) {
2559       case 8:  break;
2560       case 4:  s64 <<= 32; s64 >>= 32; break;
2561       case 2:  s64 <<= 48; s64 >>= 48; break;
2562       case 1:  s64 <<= 56; s64 >>= 56; break;
2563       default: vg_assert(0); /*NOTREACHED*/ return 0;
2564    }
2565    return s64;
2566 }
2567 
default_Addr_encoding(void)2568 static UChar default_Addr_encoding ( void )
2569 {
2570    switch (sizeof(Addr)) {
2571       case 4: return DW_EH_PE_udata4;
2572       case 8: return DW_EH_PE_udata8;
2573       default: vg_assert(0);
2574    }
2575 }
2576 
size_of_encoded_Addr(UChar encoding)2577 static UInt size_of_encoded_Addr ( UChar encoding )
2578 {
2579    if (encoding == DW_EH_PE_omit)
2580       return 0;
2581 
2582    switch (encoding & 0x07) {
2583       case DW_EH_PE_absptr: return sizeof(Addr);
2584       case DW_EH_PE_udata2: return sizeof(UShort);
2585       case DW_EH_PE_udata4: return sizeof(UInt);
2586       case DW_EH_PE_udata8: return sizeof(ULong);
2587       default: vg_assert(0);
2588    }
2589 }
2590 
read_encoded_Addr(Int * nbytes,AddressDecodingInfo * adi,UChar * data)2591 static Addr read_encoded_Addr ( /*OUT*/Int* nbytes,
2592                                 AddressDecodingInfo* adi,
2593                                 UChar* data )
2594 {
2595    /* Regarding the handling of DW_EH_PE_absptr.  DWARF3 says this
2596       denotes an absolute address, hence you would think 'base' is
2597       zero.  However, that is nonsensical (unless relocations are to
2598       be applied to the unwind data before reading it, which sounds
2599       unlikely).  My interpretation is that DW_EH_PE_absptr indicates
2600       an address relative to where the object was loaded (technically,
2601       relative to its stated load VMA, hence the use of text_bias
2602       rather than text_avma).  Hmm, should we use text_bias or
2603       text_avma here?  Not sure.
2604 
2605       This view appears to be supported by DWARF3 spec sec 7.3
2606       "Executable Objects and Shared Objects":
2607 
2608          This requirement makes the debugging information for shared
2609          objects position independent.  Virtual addresses in a shared
2610          object may be calculated by adding the offset to the base
2611          address at which the object was attached.  This offset is
2612          available in the run-time linker's data structures.
2613    */
2614    Addr   base;
2615    Word   offset;
2616    UChar  encoding      = adi->encoding;
2617    UChar* ehframe_image = adi->ehframe_image;
2618    Addr   ehframe_avma  = adi->ehframe_avma;
2619 
2620    vg_assert((encoding & DW_EH_PE_indirect) == 0);
2621 
2622    *nbytes = 0;
2623 
2624    switch (encoding & 0x70) {
2625       case DW_EH_PE_absptr:
2626          base = adi->text_bias;
2627          break;
2628       case DW_EH_PE_pcrel:
2629          base = ehframe_avma + ( data - ehframe_image );
2630          break;
2631       case DW_EH_PE_datarel:
2632          vg_assert(0);
2633          base = /* data base address */ 0;
2634          break;
2635       case DW_EH_PE_textrel:
2636          vg_assert(0);
2637          base = /* text base address */ 0;
2638          break;
2639       case DW_EH_PE_funcrel:
2640          base = 0;
2641          break;
2642       case DW_EH_PE_aligned:
2643          base = 0;
2644          offset = data - ehframe_image;
2645          if ((offset % sizeof(Addr)) != 0) {
2646             *nbytes = sizeof(Addr) - (offset % sizeof(Addr));
2647             data += *nbytes;
2648          }
2649          break;
2650       default:
2651          vg_assert(0);
2652    }
2653 
2654    if ((encoding & 0x07) == 0x00)
2655       encoding |= default_Addr_encoding();
2656 
2657    switch (encoding & 0x0f) {
2658       case DW_EH_PE_udata2:
2659          *nbytes += sizeof(UShort);
2660          return base + read_UShort(data);
2661       case DW_EH_PE_udata4:
2662          *nbytes += sizeof(UInt);
2663          return base + read_UInt(data);
2664       case DW_EH_PE_udata8:
2665          *nbytes += sizeof(ULong);
2666          return base + read_ULong(data);
2667       case DW_EH_PE_sdata2:
2668          *nbytes += sizeof(Short);
2669          return base + read_Short(data);
2670       case DW_EH_PE_sdata4:
2671          *nbytes += sizeof(Int);
2672          return base + read_Int(data);
2673       case DW_EH_PE_sdata8:
2674          *nbytes += sizeof(Long);
2675          return base + read_Long(data);
2676       default:
2677          vg_assert2(0, "read encoded address %d\n", encoding & 0x0f);
2678    }
2679 }
2680 
2681 
2682 /* ------------ Run/show DWARF3 expressions ---------- */
2683 
2684 /* Convert the DWARF3 expression in expr[0 .. exprlen-1] into a dag
2685    (of CfiExprs) stored in ctx->exprs, and return the index in
2686    ctx->exprs of the root node.  Or fail in which case return -1. */
2687 /* IMPORTANT: when adding expression forms here, also remember to
2688    add suitable evaluation code in evalCfiExpr in debuginfo.c. */
dwarfexpr_to_dag(UnwindContext * ctx,UChar * expr,Int exprlen,Bool push_cfa_at_start,Bool ddump_frames)2689 static Int dwarfexpr_to_dag ( UnwindContext* ctx,
2690                               UChar* expr, Int exprlen,
2691                               Bool push_cfa_at_start,
2692                               Bool ddump_frames )
2693 {
2694 #  define N_EXPR_STACK 20
2695 
2696 #  define PUSH(_arg)                               \
2697       do {                                         \
2698          vg_assert(sp >= -1 && sp < N_EXPR_STACK); \
2699          if (sp == N_EXPR_STACK-1)                 \
2700             return -1;                             \
2701          sp++;                                     \
2702          stack[sp] = (_arg);                       \
2703       } while (0)
2704 
2705 #  define POP(_lval)                               \
2706       do {                                         \
2707          vg_assert(sp >= -1 && sp < N_EXPR_STACK); \
2708          if (sp == -1)                             \
2709             return -1;                             \
2710          _lval = stack[sp];                        \
2711          sp--;                                     \
2712       } while (0)
2713 
2714    Int    ix, ix2, reg;
2715    UChar  opcode;
2716    Word   sw;
2717    UWord  uw;
2718    CfiOp  op;
2719    HChar* opname;
2720 
2721    Int sp; /* # of top element: valid is -1 .. N_EXPR_STACK-1 */
2722    Int stack[N_EXPR_STACK];  /* indices into ctx->exprs */
2723    struct UnwindContextState* ctxs = &ctx->state[ctx->state_sp];
2724 
2725    XArray* dst   = ctx->exprs;
2726    UChar*  limit = expr + exprlen;
2727 
2728    vg_assert(dst);
2729    vg_assert(exprlen >= 0);
2730 
2731    sp = -1; /* empty */
2732 
2733    /* Synthesise the CFA as a CfiExpr */
2734    if (push_cfa_at_start) {
2735       if (ctxs->cfa_is_regoff) {
2736          /* cfa is reg +/- offset */
2737          ix = ML_(CfiExpr_Binop)( dst,
2738                  Cop_Add,
2739                  ML_(CfiExpr_DwReg)( dst, ctxs->cfa_reg ),
2740                  ML_(CfiExpr_Const)( dst, (UWord)(Word)ctxs->cfa_off )
2741               );
2742          PUSH(ix);
2743       } else {
2744          /* CFA is already an expr; use its root node */
2745          PUSH(ctxs->cfa_expr_ix);
2746       }
2747    }
2748 
2749    while (True) {
2750 
2751       vg_assert(sp >= -1 && sp < N_EXPR_STACK);
2752 
2753       if (expr > limit)
2754          return -1;  /* overrun - something's wrong */
2755 
2756       if (expr == limit) {
2757         /* end of expr - return expr on the top of stack. */
2758         if (sp == -1)
2759            return -1; /* stack empty.  Bad. */
2760         else
2761            break;
2762       }
2763 
2764       op = 0; opname = NULL; /* excessively conservative */
2765 
2766       opcode = *expr++;
2767       switch (opcode) {
2768 
2769          case DW_OP_lit0 ... DW_OP_lit31:
2770             /* push: literal 0 .. 31 */
2771             sw = (Word)opcode - (Word)DW_OP_lit0;
2772             vg_assert(sw >= 0 && sw <= 31);
2773             PUSH( ML_(CfiExpr_Const)( dst, (UWord)sw ) );
2774             if (ddump_frames)
2775                VG_(printf)("DW_OP_lit%ld", sw);
2776             break;
2777 
2778          case DW_OP_breg0 ... DW_OP_breg31:
2779             /* push: reg + sleb128 */
2780             reg = (Int)opcode - (Int)DW_OP_breg0;
2781             vg_assert(reg >= 0 && reg <= 31);
2782             sw = read_leb128S( &expr );
2783             ix = ML_(CfiExpr_Binop)( dst,
2784                     Cop_Add,
2785                     ML_(CfiExpr_DwReg)( dst, reg ),
2786                     ML_(CfiExpr_Const)( dst, (UWord)sw )
2787                  );
2788             PUSH(ix);
2789             if (ddump_frames)
2790                VG_(printf)("DW_OP_breg%d: %ld", reg, sw);
2791             break;
2792 
2793          case DW_OP_reg0 ... DW_OP_reg31:
2794             /* push: reg */
2795             reg = (Int)opcode - (Int)DW_OP_reg0;
2796             vg_assert(reg >= 0 && reg <= 31);
2797             ix = ML_(CfiExpr_DwReg)( dst, reg );
2798             PUSH(ix);
2799             if (ddump_frames)
2800                VG_(printf)("DW_OP_reg%d", reg);
2801             break;
2802 
2803          case DW_OP_plus_uconst:
2804             uw = read_leb128U( &expr );
2805             PUSH( ML_(CfiExpr_Const)( dst, uw ) );
2806             POP( ix );
2807             POP( ix2 );
2808             PUSH( ML_(CfiExpr_Binop)( dst, op, ix2, ix ) );
2809             if (ddump_frames)
2810                VG_(printf)("DW_OP_plus_uconst: %lu", uw);
2811             break;
2812 
2813          case DW_OP_const4s:
2814             /* push: 32-bit signed immediate */
2815             sw = read_le_s_encoded_literal( expr, 4 );
2816             expr += 4;
2817             PUSH( ML_(CfiExpr_Const)( dst, (UWord)sw ) );
2818             if (ddump_frames)
2819                VG_(printf)("DW_OP_const4s: %ld", sw);
2820             break;
2821 
2822          case DW_OP_const1s:
2823             /* push: 8-bit signed immediate */
2824             sw = read_le_s_encoded_literal( expr, 1 );
2825             expr += 1;
2826             PUSH( ML_(CfiExpr_Const)( dst, (UWord)sw ) );
2827             if (ddump_frames)
2828                VG_(printf)("DW_OP_const1s: %ld", sw);
2829             break;
2830 
2831          case DW_OP_minus:
2832             op = Cop_Sub; opname = "minus"; goto binop;
2833          case DW_OP_plus:
2834             op = Cop_Add; opname = "plus"; goto binop;
2835          case DW_OP_and:
2836             op = Cop_And; opname = "and"; goto binop;
2837          case DW_OP_mul:
2838             op = Cop_Mul; opname = "mul"; goto binop;
2839          binop:
2840             POP( ix );
2841             POP( ix2 );
2842             PUSH( ML_(CfiExpr_Binop)( dst, op, ix2, ix ) );
2843             if (ddump_frames)
2844                VG_(printf)("DW_OP_%s", opname);
2845             break;
2846 
2847          case DW_OP_deref:
2848             POP( ix );
2849             PUSH( ML_(CfiExpr_Deref)( dst, ix ) );
2850             if (ddump_frames)
2851                VG_(printf)("DW_OP_deref");
2852             break;
2853 
2854          default:
2855             if (!VG_(clo_xml))
2856                VG_(message)(Vg_DebugMsg,
2857                             "Warning: DWARF2 CFI reader: unhandled DW_OP_ "
2858                             "opcode 0x%x\n", (Int)opcode);
2859             return -1;
2860       }
2861 
2862       if (expr < limit && ddump_frames)
2863          VG_(printf)("; ");
2864 
2865    }
2866 
2867    vg_assert(sp >= -1 && sp < N_EXPR_STACK);
2868    if (sp == -1)
2869       return -1;
2870 
2871    if (0 && ddump_frames)
2872       ML_(ppCfiExpr)( dst, stack[sp] );
2873    return stack[sp];
2874 
2875 #  undef POP
2876 #  undef PUSH
2877 #  undef N_EXPR_STACK
2878 }
2879 
2880 
2881 /* ------------ Run/show CFI instructions ------------ */
2882 
2883 /* Run a CFI instruction, and also return its length.
2884    Returns 0 if the instruction could not be executed.
2885 */
run_CF_instruction(UnwindContext * ctx,UChar * instr,UnwindContext * restore_ctx,AddressDecodingInfo * adi,struct _DebugInfo * di)2886 static Int run_CF_instruction ( /*MOD*/UnwindContext* ctx,
2887                                 UChar* instr,
2888                                 UnwindContext* restore_ctx,
2889                                 AddressDecodingInfo* adi,
2890                                 struct _DebugInfo* di )
2891 {
2892    Int    off, reg, reg2, nleb, len;
2893    UInt   delta;
2894    UChar* expr;
2895    Int    j;
2896    Int    i   = 0;
2897    UChar  hi2 = (instr[i] >> 6) & 3;
2898    UChar  lo6 = instr[i] & 0x3F;
2899    Addr   printing_bias = ((Addr)ctx->initloc) - ((Addr)di->text_bias);
2900    struct UnwindContextState* ctxs;
2901    i++;
2902 
2903    if (ctx->state_sp < 0 || ctx->state_sp >= N_RR_STACK)
2904       return 0; /* bogus reg-rule stack pointer */
2905 
2906    ctxs = &ctx->state[ctx->state_sp];
2907    if (hi2 == DW_CFA_advance_loc) {
2908       delta = (UInt)lo6;
2909       delta *= ctx->code_a_f;
2910       ctx->loc += delta;
2911       if (di->ddump_frames)
2912          VG_(printf)("  DW_CFA_advance_loc: %d to %08lx\n",
2913                      (Int)delta, (Addr)ctx->loc + printing_bias);
2914       return i;
2915    }
2916 
2917    if (hi2 == DW_CFA_offset) {
2918       /* Set rule for reg 'lo6' to CFAOff(off * data_af) */
2919       off = read_leb128( &instr[i], &nleb, 0 );
2920       i += nleb;
2921       reg = (Int)lo6;
2922       if (reg < 0 || reg >= N_CFI_REGS)
2923          return 0; /* fail */
2924       ctxs->reg[reg].tag = RR_CFAOff;
2925       ctxs->reg[reg].arg = off * ctx->data_a_f;
2926       if (di->ddump_frames)
2927          VG_(printf)("  DW_CFA_offset: r%d at cfa%s%d\n",
2928                      (Int)reg,
2929                      ctxs->reg[reg].arg < 0 ? "" : "+",
2930                      (Int)ctxs->reg[reg].arg );
2931       return i;
2932    }
2933 
2934    if (hi2 == DW_CFA_restore) {
2935       reg = (Int)lo6;
2936       if (reg < 0 || reg >= N_CFI_REGS)
2937          return 0; /* fail */
2938       if (restore_ctx == NULL)
2939          return 0; /* fail */
2940       ctxs->reg[reg] = restore_ctx->state[restore_ctx->state_sp].reg[reg];
2941       if (di->ddump_frames)
2942          VG_(printf)("  DW_CFA_restore: r%d\n", (Int)reg);
2943       return i;
2944    }
2945 
2946    vg_assert(hi2 == DW_CFA_use_secondary);
2947 
2948    switch (lo6) {
2949       case DW_CFA_nop:
2950          if (di->ddump_frames)
2951             VG_(printf)("  DW_CFA_nop\n");
2952          break;
2953       case DW_CFA_set_loc:
2954          /* WAS:
2955             ctx->loc = read_Addr(&instr[i]) - ctx->initloc; i+= sizeof(Addr);
2956             Was this ever right? */
2957          /* 2007 Feb 23: No.  binutils/dwarf.c treats it as an encoded
2958             address and that appears to be in accordance with the
2959             DWARF3 spec. */
2960          ctx->loc = read_encoded_Addr(&len, adi, &instr[i]);
2961          i += len;
2962          if (di->ddump_frames)
2963             VG_(printf)("  rci:DW_CFA_set_loc\n");
2964          break;
2965       case DW_CFA_advance_loc1:
2966          delta = (UInt)read_UChar(&instr[i]); i+= sizeof(UChar);
2967          delta *= ctx->code_a_f;
2968          ctx->loc += delta;
2969          if (di->ddump_frames)
2970             VG_(printf)("  DW_CFA_advance_loc1: %d to %08lx\n",
2971                         (Int)delta, (Addr)ctx->loc + printing_bias);
2972          break;
2973       case DW_CFA_advance_loc2:
2974          delta = (UInt)read_UShort(&instr[i]); i+= sizeof(UShort);
2975          delta *= ctx->code_a_f;
2976          ctx->loc += delta;
2977          if (di->ddump_frames)
2978             VG_(printf)("  DW_CFA_advance_loc2: %d to %08lx\n",
2979                         (Int)delta, (Addr)ctx->loc + printing_bias);
2980          break;
2981       case DW_CFA_advance_loc4:
2982          delta = (UInt)read_UInt(&instr[i]); i+= sizeof(UInt);
2983          delta *= ctx->code_a_f;
2984          ctx->loc += delta;
2985          if (di->ddump_frames)
2986             VG_(printf)("  DW_CFA_advance_loc4: %d to %08lx\n",
2987                         (Int)delta, (Addr)ctx->loc + printing_bias);
2988          break;
2989 
2990       case DW_CFA_def_cfa:
2991          reg = read_leb128( &instr[i], &nleb, 0 );
2992          i += nleb;
2993          off = read_leb128( &instr[i], &nleb, 0 );
2994          i += nleb;
2995          if (reg < 0 || reg >= N_CFI_REGS)
2996             return 0; /* fail */
2997          ctxs->cfa_is_regoff = True;
2998          ctxs->cfa_expr_ix   = 0;
2999          ctxs->cfa_reg       = reg;
3000          ctxs->cfa_off       = off;
3001          if (di->ddump_frames)
3002             VG_(printf)("  DW_CFA_def_cfa: r%d ofs %d\n", (Int)reg, (Int)off);
3003          break;
3004 
3005       case DW_CFA_def_cfa_sf:
3006          reg = read_leb128( &instr[i], &nleb, 0 );
3007          i += nleb;
3008          off = read_leb128( &instr[i], &nleb, 1 );
3009          i += nleb;
3010          if (reg < 0 || reg >= N_CFI_REGS)
3011             return 0; /* fail */
3012          ctxs->cfa_is_regoff = True;
3013          ctxs->cfa_expr_ix   = 0;
3014          ctxs->cfa_reg       = reg;
3015          ctxs->cfa_off       = off * ctx->data_a_f;
3016          if (di->ddump_frames)
3017             VG_(printf)("  rci:DW_CFA_def_cfa_sf\n");
3018          break;
3019 
3020       case DW_CFA_register:
3021          reg = read_leb128( &instr[i], &nleb, 0);
3022          i += nleb;
3023          reg2 = read_leb128( &instr[i], &nleb, 0);
3024          i += nleb;
3025          if (reg < 0 || reg >= N_CFI_REGS)
3026             return 0; /* fail */
3027          if (reg2 < 0 || reg2 >= N_CFI_REGS)
3028             return 0; /* fail */
3029          ctxs->reg[reg].tag = RR_Reg;
3030          ctxs->reg[reg].arg = reg2;
3031          if (di->ddump_frames)
3032             VG_(printf)("  DW_CFA_register: r%d in r%d\n",
3033                         (Int)reg, (Int)reg2);
3034          break;
3035 
3036       case DW_CFA_offset_extended:
3037          reg = read_leb128( &instr[i], &nleb, 0 );
3038          i += nleb;
3039          off = read_leb128( &instr[i], &nleb, 0 );
3040          i += nleb;
3041          if (reg < 0 || reg >= N_CFI_REGS)
3042             return 0; /* fail */
3043          ctxs->reg[reg].tag = RR_CFAOff;
3044          ctxs->reg[reg].arg = off * ctx->data_a_f;
3045          if (di->ddump_frames)
3046             VG_(printf)("  rci:DW_CFA_offset_extended\n");
3047          break;
3048 
3049       case DW_CFA_offset_extended_sf:
3050          reg = read_leb128( &instr[i], &nleb, 0 );
3051          i += nleb;
3052          off = read_leb128( &instr[i], &nleb, 1 );
3053          i += nleb;
3054          if (reg < 0 || reg >= N_CFI_REGS)
3055             return 0; /* fail */
3056          ctxs->reg[reg].tag = RR_CFAOff;
3057          ctxs->reg[reg].arg = off * ctx->data_a_f;
3058          if (di->ddump_frames)
3059             VG_(printf)("  DW_CFA_offset_extended_sf: r%d at cfa%s%d\n",
3060                         reg,
3061                         ctxs->reg[reg].arg < 0 ? "" : "+",
3062                         (Int)ctxs->reg[reg].arg);
3063          break;
3064 
3065       case DW_CFA_GNU_negative_offset_extended:
3066          reg = read_leb128( &instr[i], &nleb, 0 );
3067          i += nleb;
3068          off = read_leb128( &instr[i], &nleb, 0 );
3069          i += nleb;
3070          if (reg < 0 || reg >= N_CFI_REGS)
3071             return 0; /* fail */
3072          ctxs->reg[reg].tag = RR_CFAOff;
3073          ctxs->reg[reg].arg = (-off) * ctx->data_a_f;
3074          if (di->ddump_frames)
3075             VG_(printf)("  rci:DW_CFA_GNU_negative_offset_extended\n");
3076          break;
3077 
3078       case DW_CFA_restore_extended:
3079          reg = read_leb128( &instr[i], &nleb, 0 );
3080          i += nleb;
3081          if (reg < 0 || reg >= N_CFI_REGS)
3082             return 0; /* fail */
3083 	 if (restore_ctx == NULL)
3084 	    return 0; /* fail */
3085 	 ctxs->reg[reg] = restore_ctx->state[restore_ctx->state_sp].reg[reg];
3086          if (di->ddump_frames)
3087             VG_(printf)("  rci:DW_CFA_restore_extended\n");
3088          break;
3089 
3090       case DW_CFA_val_offset:
3091          reg = read_leb128( &instr[i], &nleb, 0 );
3092          i += nleb;
3093          off = read_leb128( &instr[i], &nleb, 0 );
3094          i += nleb;
3095          if (reg < 0 || reg >= N_CFI_REGS)
3096             return 0; /* fail */
3097          ctxs->reg[reg].tag = RR_CFAValOff;
3098          ctxs->reg[reg].arg = off * ctx->data_a_f;
3099          if (di->ddump_frames)
3100             VG_(printf)("  rci:DW_CFA_val_offset\n");
3101          break;
3102 
3103       case DW_CFA_val_offset_sf:
3104          reg = read_leb128( &instr[i], &nleb, 0 );
3105          i += nleb;
3106          off = read_leb128( &instr[i], &nleb, 1 );
3107          i += nleb;
3108          if (reg < 0 || reg >= N_CFI_REGS)
3109             return 0; /* fail */
3110          ctxs->reg[reg].tag = RR_CFAValOff;
3111          ctxs->reg[reg].arg = off * ctx->data_a_f;
3112          if (di->ddump_frames)
3113             VG_(printf)("  rci:DW_CFA_val_offset_sf\n");
3114          break;
3115 
3116       case DW_CFA_def_cfa_register:
3117          reg = read_leb128( &instr[i], &nleb, 0);
3118          i += nleb;
3119          if (reg < 0 || reg >= N_CFI_REGS)
3120             return 0; /* fail */
3121          ctxs->cfa_is_regoff = True;
3122          ctxs->cfa_expr_ix   = 0;
3123          ctxs->cfa_reg       = reg;
3124          /* ->cfa_off unchanged */
3125          if (di->ddump_frames)
3126             VG_(printf)("  DW_CFA_def_cfa_register: r%d\n", (Int)reg );
3127          break;
3128 
3129       case DW_CFA_def_cfa_offset:
3130          off = read_leb128( &instr[i], &nleb, 0);
3131          i += nleb;
3132          ctxs->cfa_is_regoff = True;
3133          ctxs->cfa_expr_ix   = 0;
3134          /* ->reg is unchanged */
3135          ctxs->cfa_off       = off;
3136          if (di->ddump_frames)
3137             VG_(printf)("  DW_CFA_def_cfa_offset: %d\n", (Int)off);
3138          break;
3139 
3140       case DW_CFA_def_cfa_offset_sf:
3141          off = read_leb128( &instr[i], &nleb, 1);
3142          i += nleb;
3143          ctxs->cfa_is_regoff = True;
3144          ctxs->cfa_expr_ix   = 0;
3145          /* ->reg is unchanged */
3146          ctxs->cfa_off       = off * ctx->data_a_f;
3147          if (di->ddump_frames)
3148             VG_(printf)("  DW_CFA_def_cfa_offset_sf: %d\n", ctxs->cfa_off);
3149          break;
3150 
3151       case DW_CFA_undefined:
3152          reg = read_leb128( &instr[i], &nleb, 0);
3153          i += nleb;
3154          if (reg < 0 || reg >= N_CFI_REGS)
3155             return 0; /* fail */
3156          ctxs->reg[reg].tag = RR_Undef;
3157          ctxs->reg[reg].arg = 0;
3158          if (di->ddump_frames)
3159             VG_(printf)("  rci:DW_CFA_undefined\n");
3160          break;
3161 
3162       case DW_CFA_same_value:
3163          reg = read_leb128( &instr[i], &nleb, 0);
3164          i += nleb;
3165          if (reg < 0 || reg >= N_CFI_REGS)
3166             return 0; /* fail */
3167          ctxs->reg[reg].tag = RR_Same;
3168          ctxs->reg[reg].arg = 0;
3169          if (di->ddump_frames)
3170             VG_(printf)("  rci:DW_CFA_same_value\n");
3171          break;
3172 
3173       case DW_CFA_GNU_args_size:
3174          /* No idea what is supposed to happen.  gdb-6.3 simply
3175             ignores these. */
3176          /*off = */ read_leb128( &instr[i], &nleb, 0 );
3177          i += nleb;
3178          if (di->ddump_frames)
3179             VG_(printf)("  rci:DW_CFA_GNU_args_size (ignored)\n");
3180          break;
3181 
3182       case DW_CFA_expression:
3183          /* Identical to DW_CFA_val_expression except that the value
3184             computed is an address and so needs one final
3185             dereference. */
3186          reg = read_leb128( &instr[i], &nleb, 0 );
3187          i += nleb;
3188          len = read_leb128( &instr[i], &nleb, 0 );
3189          i += nleb;
3190          expr = &instr[i];
3191          i += len;
3192          if (reg < 0 || reg >= N_CFI_REGS)
3193             return 0; /* fail */
3194          if (di->ddump_frames)
3195             VG_(printf)("  DW_CFA_expression: r%d (",
3196                         (Int)reg);
3197          /* Convert the expression into a dag rooted at ctx->exprs index j,
3198             or fail. */
3199          j = dwarfexpr_to_dag ( ctx, expr, len, True/*push CFA at start*/,
3200                                 di->ddump_frames);
3201          if (di->ddump_frames)
3202             VG_(printf)(")\n");
3203          vg_assert(j >= -1);
3204          if (j >= 0) {
3205             vg_assert(ctx->exprs);
3206             vg_assert( j < VG_(sizeXA)(ctx->exprs) );
3207          }
3208          if (j == -1)
3209             return 0; /* fail */
3210          /* Add an extra dereference */
3211          j = ML_(CfiExpr_Deref)( ctx->exprs, j );
3212          ctxs->reg[reg].tag = RR_ValExpr;
3213          ctxs->reg[reg].arg = j;
3214          break;
3215 
3216       case DW_CFA_val_expression:
3217          reg = read_leb128( &instr[i], &nleb, 0 );
3218          i += nleb;
3219          len = read_leb128( &instr[i], &nleb, 0 );
3220          i += nleb;
3221          expr = &instr[i];
3222          i += len;
3223          if (reg < 0 || reg >= N_CFI_REGS)
3224             return 0; /* fail */
3225          if (di->ddump_frames)
3226             VG_(printf)("  DW_CFA_val_expression: r%d (",
3227                         (Int)reg);
3228          /* Convert the expression into a dag rooted at ctx->exprs index j,
3229             or fail. */
3230          j = dwarfexpr_to_dag ( ctx, expr, len, True/*push CFA at start*/,
3231                                 di->ddump_frames);
3232          if (di->ddump_frames)
3233             VG_(printf)(")\n");
3234          vg_assert(j >= -1);
3235          if (j >= 0) {
3236             vg_assert(ctx->exprs);
3237             vg_assert( j < VG_(sizeXA)(ctx->exprs) );
3238          }
3239          if (j == -1)
3240             return 0; /* fail */
3241          ctxs->reg[reg].tag = RR_ValExpr;
3242          ctxs->reg[reg].arg = j;
3243          break;
3244 
3245       case DW_CFA_def_cfa_expression:
3246          len = read_leb128( &instr[i], &nleb, 0 );
3247          i += nleb;
3248          expr = &instr[i];
3249          i += len;
3250          if (di->ddump_frames)
3251             VG_(printf)("  DW_CFA_def_cfa_expression (");
3252          /* Convert the expression into a dag rooted at ctx->exprs index j,
3253             or fail. */
3254          j = dwarfexpr_to_dag ( ctx, expr, len, True/*push CFA at start*/,
3255                                 di->ddump_frames);
3256          if (di->ddump_frames)
3257             VG_(printf)(")\n");
3258          ctxs->cfa_is_regoff = False;
3259          ctxs->cfa_reg       = 0;
3260          ctxs->cfa_off       = 0;
3261          ctxs->cfa_expr_ix   = j;
3262          break;
3263 
3264       case DW_CFA_GNU_window_save:
3265          /* Ignored.  This appears to be sparc-specific; quite why it
3266             turns up in SuSE-supplied x86 .so's beats me. */
3267          if (di->ddump_frames)
3268             VG_(printf)("  DW_CFA_GNU_window_save\n");
3269          break;
3270 
3271       case DW_CFA_remember_state:
3272          if (di->ddump_frames)
3273             VG_(printf)("  DW_CFA_remember_state\n");
3274          /* we just checked this at entry, so: */
3275          vg_assert(ctx->state_sp >= 0 && ctx->state_sp < N_RR_STACK);
3276          ctx->state_sp++;
3277          if (ctx->state_sp == N_RR_STACK) {
3278             /* stack overflow.  We're hosed. */
3279             VG_(message)(Vg_DebugMsg, "DWARF2 CFI reader: N_RR_STACK is "
3280                                       "too low; increase and recompile.");
3281             i = 0; /* indicate failure */
3282          } else {
3283             VG_(memcpy)(/*dst*/&ctx->state[ctx->state_sp],
3284                         /*src*/&ctx->state[ctx->state_sp - 1],
3285                         sizeof(ctx->state[ctx->state_sp]) );
3286          }
3287          break;
3288 
3289       case DW_CFA_restore_state:
3290          if (di->ddump_frames)
3291             VG_(printf)("  DW_CFA_restore_state\n");
3292          /* we just checked this at entry, so: */
3293          vg_assert(ctx->state_sp >= 0 && ctx->state_sp < N_RR_STACK);
3294          if (ctx->state_sp == 0) {
3295             /* stack overflow.  Give up. */
3296             i = 0; /* indicate failure */
3297          } else {
3298             /* simply fall back to previous entry */
3299             ctx->state_sp--;
3300          }
3301          break;
3302 
3303       default:
3304          VG_(message)(Vg_DebugMsg, "DWARF2 CFI reader: unhandled CFI "
3305                                    "instruction 0:%d\n", (Int)lo6);
3306          if (di->ddump_frames)
3307             VG_(printf)("  rci:run_CF_instruction:default\n");
3308          i = 0;
3309          break;
3310    }
3311 
3312    return i;
3313 }
3314 
3315 
3316 /* Show a CFI instruction, and also return its length.  Show it as
3317    close as possible (preferably identical) to how GNU binutils
3318    readelf --debug-dump=frames would. */
3319 
show_CF_instruction(UChar * instr,AddressDecodingInfo * adi,Int code_a_f,Int data_a_f)3320 static Int show_CF_instruction ( UChar* instr,
3321                                  AddressDecodingInfo* adi,
3322                                  Int code_a_f, Int data_a_f )
3323 {
3324    UInt  delta;
3325    Int   off, coff, reg, reg2, nleb, len;
3326    Addr  loc;
3327    Int   i   = 0;
3328    UChar hi2 = (instr[i] >> 6) & 3;
3329    UChar lo6 = instr[i] & 0x3F;
3330    i++;
3331 
3332    if (0) VG_(printf)("raw:%x/%x:%x:%x:%x:%x:%x:%x:%x:%x\n",
3333                       hi2, lo6,
3334                       instr[i+0], instr[i+1], instr[i+2], instr[i+3],
3335                       instr[i+4], instr[i+5], instr[i+6], instr[i+7] );
3336 
3337    if (hi2 == DW_CFA_advance_loc) {
3338       VG_(printf)("  sci:DW_CFA_advance_loc(%d)\n", (Int)lo6);
3339       return i;
3340    }
3341 
3342    if (hi2 == DW_CFA_offset) {
3343       off = read_leb128( &instr[i], &nleb, 0 );
3344       i += nleb;
3345       coff = off * data_a_f;
3346       VG_(printf)("  DW_CFA_offset: r%d at cfa%s%d\n",
3347                   (Int)lo6, coff < 0 ? "" : "+", (Int)coff );
3348       return i;
3349    }
3350 
3351    if (hi2 == DW_CFA_restore) {
3352       VG_(printf)("  sci:DW_CFA_restore(r%d)\n", (Int)lo6);
3353       return i;
3354    }
3355 
3356    vg_assert(hi2 == DW_CFA_use_secondary);
3357 
3358    switch (lo6) {
3359 
3360       case DW_CFA_nop:
3361          VG_(printf)("  DW_CFA_nop\n");
3362          break;
3363 
3364       case DW_CFA_set_loc:
3365          /* WAS: loc = read_Addr(&instr[i]); i+= sizeof(Addr);
3366             (now known to be incorrect -- the address is encoded) */
3367          loc = read_encoded_Addr(&len, adi, &instr[i]);
3368          i += len;
3369          VG_(printf)("  sci:DW_CFA_set_loc(%#lx)\n", loc);
3370          break;
3371 
3372       case DW_CFA_advance_loc1:
3373          delta = (UInt)read_UChar(&instr[i]); i+= sizeof(UChar);
3374          VG_(printf)("  sci:DW_CFA_advance_loc1(%d)\n", delta);
3375          break;
3376 
3377       case DW_CFA_advance_loc2:
3378          delta = (UInt)read_UShort(&instr[i]); i+= sizeof(UShort);
3379          VG_(printf)("  sci:DW_CFA_advance_loc2(%d)\n", delta);
3380          break;
3381 
3382       case DW_CFA_advance_loc4:
3383          delta = (UInt)read_UInt(&instr[i]); i+= sizeof(UInt);
3384          VG_(printf)("  DW_CFA_advance_loc4(%d)\n", delta);
3385          break;
3386 
3387       case DW_CFA_def_cfa:
3388          reg = read_leb128( &instr[i], &nleb, 0 );
3389          i += nleb;
3390          off = read_leb128( &instr[i], &nleb, 0 );
3391          i += nleb;
3392          VG_(printf)("  DW_CFA_def_cfa: r%d ofs %d\n", (Int)reg, (Int)off);
3393          break;
3394 
3395       case DW_CFA_def_cfa_sf:
3396          reg = read_leb128( &instr[i], &nleb, 0 );
3397          i += nleb;
3398          off = read_leb128( &instr[i], &nleb, 1 );
3399          i += nleb;
3400          VG_(printf)("  DW_CFA_def_cfa_sf: r%d ofs %d\n",
3401                      (Int)reg, (Int)(off * data_a_f));
3402          break;
3403 
3404       case DW_CFA_register:
3405          reg = read_leb128( &instr[i], &nleb, 0);
3406          i += nleb;
3407          reg2 = read_leb128( &instr[i], &nleb, 0);
3408          i += nleb;
3409          VG_(printf)("  sci:DW_CFA_register(r%d, r%d)\n", reg, reg2);
3410          break;
3411 
3412       case DW_CFA_def_cfa_register:
3413          reg = read_leb128( &instr[i], &nleb, 0);
3414          i += nleb;
3415          VG_(printf)("  sci:DW_CFA_def_cfa_register(r%d)\n", reg);
3416          break;
3417 
3418       case DW_CFA_def_cfa_offset:
3419          off = read_leb128( &instr[i], &nleb, 0);
3420          i += nleb;
3421          VG_(printf)("  sci:DW_CFA_def_cfa_offset(%d)\n", off);
3422          break;
3423 
3424       case DW_CFA_def_cfa_offset_sf:
3425          off = read_leb128( &instr[i], &nleb, 1);
3426          i += nleb;
3427          VG_(printf)("  sci:DW_CFA_def_cfa_offset_sf(%d)\n", off);
3428          break;
3429 
3430       case DW_CFA_restore_extended:
3431          reg = read_leb128( &instr[i], &nleb, 0);
3432          i += nleb;
3433          VG_(printf)("  sci:DW_CFA_restore_extended(r%d)\n", reg);
3434          break;
3435 
3436       case DW_CFA_undefined:
3437          reg = read_leb128( &instr[i], &nleb, 0);
3438          i += nleb;
3439          VG_(printf)("  sci:DW_CFA_undefined(r%d)\n", reg);
3440          break;
3441 
3442       case DW_CFA_same_value:
3443          reg = read_leb128( &instr[i], &nleb, 0);
3444          i += nleb;
3445          VG_(printf)("  sci:DW_CFA_same_value(r%d)\n", reg);
3446          break;
3447 
3448       case DW_CFA_remember_state:
3449          VG_(printf)("  sci:DW_CFA_remember_state\n");
3450          break;
3451 
3452       case DW_CFA_restore_state:
3453          VG_(printf)("  sci:DW_CFA_restore_state\n");
3454          break;
3455 
3456       case DW_CFA_GNU_args_size:
3457          off = read_leb128( &instr[i], &nleb, 0 );
3458          i += nleb;
3459          VG_(printf)("  sci:DW_CFA_GNU_args_size(%d)\n", off );
3460          break;
3461 
3462       case DW_CFA_def_cfa_expression:
3463          len = read_leb128( &instr[i], &nleb, 0 );
3464          i += nleb;
3465          i += len;
3466          VG_(printf)("  sci:DW_CFA_def_cfa_expression(length %d)\n", len);
3467          break;
3468 
3469       case DW_CFA_expression:
3470          reg = read_leb128( &instr[i], &nleb, 0 );
3471          i += nleb;
3472          len = read_leb128( &instr[i], &nleb, 0 );
3473          i += nleb;
3474          i += len;
3475          VG_(printf)("  sci:DW_CFA_expression(r%d, length %d)\n", reg, len);
3476          break;
3477 
3478       case DW_CFA_val_expression:
3479          reg = read_leb128( &instr[i], &nleb, 0 );
3480          i += nleb;
3481          len = read_leb128( &instr[i], &nleb, 0 );
3482          i += nleb;
3483          i += len;
3484          VG_(printf)("  sci:DW_CFA_val_expression(r%d, length %d)\n", reg, len);
3485          break;
3486 
3487       case DW_CFA_offset_extended:
3488          reg = read_leb128( &instr[i], &nleb, 0 );
3489          i += nleb;
3490          off = read_leb128( &instr[i], &nleb, 0 );
3491          i += nleb;
3492          VG_(printf)("  sci:DW_CFA_offset_extended(r%d, "
3493                      "off %d x data_af)\n", reg, off);
3494          break;
3495 
3496       case DW_CFA_offset_extended_sf:
3497          reg = read_leb128( &instr[i], &nleb, 0 );
3498          i += nleb;
3499          off = read_leb128( &instr[i], &nleb, 1 );
3500          i += nleb;
3501 	 coff = (Int)(off * data_a_f);
3502          VG_(printf)("  DW_CFA_offset_extended_sf: r%d at cfa%s%d\n",
3503                         reg, coff < 0 ? "" : "+", coff);
3504          break;
3505 
3506       case DW_CFA_GNU_negative_offset_extended:
3507          reg = read_leb128( &instr[i], &nleb, 0 );
3508          i += nleb;
3509          off = read_leb128( &instr[i], &nleb, 0 );
3510          i += nleb;
3511          VG_(printf)("  sci:DW_CFA_GNU_negative_offset_extended"
3512                      "(r%d, off %d x data_af)\n", reg, -off);
3513          break;
3514 
3515       case DW_CFA_val_offset:
3516          reg = read_leb128( &instr[i], &nleb, 0 );
3517          i += nleb;
3518          off = read_leb128( &instr[i], &nleb, 0 );
3519          i += nleb;
3520          VG_(printf)("  sci:DW_CFA_val_offset(r%d, off %d x data_af)\n",
3521                      reg, off);
3522          break;
3523 
3524        case DW_CFA_val_offset_sf:
3525          reg = read_leb128( &instr[i], &nleb, 0 );
3526          i += nleb;
3527          off = read_leb128( &instr[i], &nleb, 1 );
3528          i += nleb;
3529          VG_(printf)("  sci:DW_CFA_val_offset_sf(r%d, off %d x data_af)\n",
3530                      reg, off);
3531          break;
3532 
3533       case DW_CFA_GNU_window_save:
3534          VG_(printf)("  sci:DW_CFA_GNU_window_save\n");
3535          break;
3536 
3537       default:
3538          VG_(printf)("  sci:0:%d\n", (Int)lo6);
3539          break;
3540    }
3541 
3542    return i;
3543 }
3544 
3545 
3546 /* Show the instructions in instrs[0 .. ilen-1]. */
show_CF_instructions(UChar * instrs,Int ilen,AddressDecodingInfo * adi,Int code_a_f,Int data_a_f)3547 static void show_CF_instructions ( UChar* instrs, Int ilen,
3548                                    AddressDecodingInfo* adi,
3549                                    Int code_a_f, Int data_a_f )
3550 {
3551    Int i = 0;
3552    while (True) {
3553       if (i >= ilen) break;
3554       i += show_CF_instruction( &instrs[i], adi, code_a_f, data_a_f );
3555    }
3556 }
3557 
3558 
3559 /* Run the CF instructions in instrs[0 .. ilen-1], until the end is
3560    reached, or until there is a failure.  Return True iff success.
3561 */
3562 static
run_CF_instructions(struct _DebugInfo * di,Bool record,UnwindContext * ctx,UChar * instrs,Int ilen,UWord fde_arange,UnwindContext * restore_ctx,AddressDecodingInfo * adi)3563 Bool run_CF_instructions ( struct _DebugInfo* di,
3564                            Bool record,
3565                            UnwindContext* ctx, UChar* instrs, Int ilen,
3566                            UWord fde_arange,
3567                            UnwindContext* restore_ctx,
3568                            AddressDecodingInfo* adi )
3569 {
3570    DiCfSI cfsi;
3571    Bool summ_ok;
3572    Int j, i = 0;
3573    Addr loc_prev;
3574    if (0) ppUnwindContext(ctx);
3575    if (0) ppUnwindContext_summary(ctx);
3576    while (True) {
3577       loc_prev = ctx->loc;
3578       if (i >= ilen) break;
3579       if (0) (void)show_CF_instruction( &instrs[i], adi,
3580                                         ctx->code_a_f, ctx->data_a_f );
3581       j = run_CF_instruction( ctx, &instrs[i], restore_ctx, adi, di );
3582       if (j == 0)
3583          return False; /* execution failed */
3584       i += j;
3585       if (0) ppUnwindContext(ctx);
3586       if (record && loc_prev != ctx->loc) {
3587          summ_ok = summarise_context ( &cfsi, loc_prev, ctx, di );
3588          if (summ_ok) {
3589             ML_(addDiCfSI)(di, &cfsi);
3590             if (di->trace_cfi)
3591                ML_(ppDiCfSI)(di->cfsi_exprs, &cfsi);
3592          }
3593       }
3594    }
3595    if (ctx->loc < fde_arange) {
3596       loc_prev = ctx->loc;
3597       ctx->loc = fde_arange;
3598       if (record) {
3599          summ_ok = summarise_context ( &cfsi, loc_prev, ctx, di );
3600          if (summ_ok) {
3601             ML_(addDiCfSI)(di, &cfsi);
3602             if (di->trace_cfi)
3603                ML_(ppDiCfSI)(di->cfsi_exprs, &cfsi);
3604          }
3605       }
3606    }
3607    return True;
3608 }
3609 
3610 
3611 /* ------------ Main entry point for CFI reading ------------ */
3612 
3613 typedef
3614    struct {
3615       /* This gives the CIE an identity to which FDEs will refer. */
3616       ULong  offset;
3617       /* Code, data factors. */
3618       Int    code_a_f;
3619       Int    data_a_f;
3620       /* Return-address pseudo-register. */
3621       Int    ra_reg;
3622       UChar  address_encoding;
3623       /* Where are the instrs?  Note, this are simply pointers back to
3624          the transiently-mapped-in section. */
3625       UChar* instrs;
3626       Int    ilen;
3627       /* God knows .. don't ask */
3628       Bool   saw_z_augmentation;
3629    }
3630    CIE;
3631 
init_CIE(CIE * cie)3632 static void init_CIE ( CIE* cie )
3633 {
3634    cie->offset             = 0;
3635    cie->code_a_f           = 0;
3636    cie->data_a_f           = 0;
3637    cie->ra_reg             = 0;
3638    cie->address_encoding   = 0;
3639    cie->instrs             = NULL;
3640    cie->ilen               = 0;
3641    cie->saw_z_augmentation = False;
3642 }
3643 
3644 #define N_CIEs 8000
3645 static CIE the_CIEs[N_CIEs];
3646 
3647 
ML_(read_callframe_info_dwarf3)3648 void ML_(read_callframe_info_dwarf3)
3649         ( /*OUT*/struct _DebugInfo* di, UChar* frame_image, SizeT frame_size,
3650           Bool for_eh )
3651 {
3652    Int    nbytes;
3653    HChar* how = NULL;
3654    Int    n_CIEs = 0;
3655    UChar* data = frame_image;
3656    UWord  ehframe_cfsis = 0;
3657    Addr   frame_avma = for_eh ? di->ehframe_avma : 0;
3658 
3659 #  if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
3660    /* These targets don't use CFI-based stack unwinding.  */
3661    return;
3662 #  endif
3663 
3664    /* If we are reading .debug_frame after .eh_frame has been read, only
3665       add FDEs which weren't covered in .eh_frame.  To be able to quickly
3666       search the FDEs, the records must be sorted.  */
3667    if ( ! for_eh && di->ehframe_size && di->cfsi_used ) {
3668       ML_(canonicaliseCFI) ( di );
3669       ehframe_cfsis = di->cfsi_used;
3670    }
3671 
3672    if (di->trace_cfi) {
3673       VG_(printf)("\n-----------------------------------------------\n");
3674       VG_(printf)("CFI info: szB %ld, _avma %#lx, _image %p\n",
3675                   frame_size, frame_avma, frame_image );
3676       VG_(printf)("CFI info: name %s\n",
3677                   di->filename );
3678    }
3679 
3680    /* Loop over CIEs/FDEs */
3681 
3682    /* Conceptually, the frame info is a sequence of FDEs, one for each
3683       function.  Inside an FDE is a miniature program for a special
3684       state machine, which, when run, produces the stack-unwinding
3685       info for that function.
3686 
3687       Because the FDEs typically have much in common, and because the
3688       DWARF designers appear to have been fanatical about space
3689       saving, the common parts are factored out into so-called CIEs.
3690       That means that what we traverse is a sequence of structs, each
3691       of which is either a FDE (usually) or a CIE (occasionally).
3692       Each FDE has a field indicating which CIE is the one pertaining
3693       to it.
3694 
3695       The following loop traverses the sequence.  FDEs are dealt with
3696       immediately; once we harvest the useful info in an FDE, it is
3697       then forgotten about.  By contrast, CIEs are validated and
3698       dumped into an array, because later FDEs may refer to any
3699       previously-seen CIE.
3700    */
3701    while (True) {
3702       UChar* ciefde_start;
3703       ULong  ciefde_len;
3704       ULong  cie_pointer;
3705       Bool   dw64;
3706 
3707       /* Are we done? */
3708       if (data == frame_image + frame_size)
3709          return;
3710 
3711       /* Overshot the end?  Means something is wrong */
3712       if (data > frame_image + frame_size) {
3713          how = "overran the end of .eh_frame";
3714          goto bad;
3715       }
3716 
3717       /* Ok, we must be looking at the start of a new CIE or FDE.
3718          Figure out which it is. */
3719 
3720       ciefde_start = data;
3721       if (di->trace_cfi)
3722          VG_(printf)("\ncie/fde.start   = %p (frame_image + 0x%lx)\n",
3723                      ciefde_start,
3724                      ciefde_start - frame_image + 0UL);
3725 
3726       ciefde_len = (ULong) read_UInt(data); data += sizeof(UInt);
3727       if (di->trace_cfi)
3728          VG_(printf)("cie/fde.length  = %lld\n", ciefde_len);
3729 
3730       /* Apparently, if the .length field is zero, we are at the end
3731          of the sequence.  This is stated in the Generic Elf
3732          Specification (see comments far above here) and is one of the
3733          places where .eh_frame and .debug_frame data differ. */
3734       if (ciefde_len == 0) {
3735          if (di->ddump_frames)
3736             VG_(printf)("%08lx ZERO terminator\n\n",
3737                         ((Addr)ciefde_start) - ((Addr)frame_image));
3738          return;
3739       }
3740 
3741       /* If the .length field is 0xFFFFFFFF then we're dealing with
3742          64-bit DWARF, and the real length is stored as a 64-bit
3743          number immediately following it. */
3744       dw64 = False;
3745       if (ciefde_len == 0xFFFFFFFFUL) {
3746          dw64 = True;
3747          ciefde_len = read_ULong(data); data += sizeof(ULong);
3748       }
3749 
3750       /* Now get the CIE ID, whose size depends on the DWARF 32 vs
3751 	 64-ness. */
3752       if (dw64) {
3753          cie_pointer = read_ULong(data);
3754          data += sizeof(ULong); /* XXX see XXX below */
3755       } else {
3756          cie_pointer = (ULong)read_UInt(data);
3757          data += sizeof(UInt); /* XXX see XXX below */
3758       }
3759 
3760       if (di->trace_cfi)
3761          VG_(printf)("cie.pointer     = %lld\n", cie_pointer);
3762 
3763       /* If cie_pointer is zero for .eh_frame or all ones for .debug_frame,
3764          we've got a CIE; else it's an FDE. */
3765       if (cie_pointer == (for_eh ? 0ULL
3766                           : dw64 ? 0xFFFFFFFFFFFFFFFFULL : 0xFFFFFFFFULL)) {
3767 
3768          Int    this_CIE;
3769          UChar  cie_version;
3770          UChar* cie_augmentation;
3771 
3772          /* --------- CIE --------- */
3773 	 if (di->trace_cfi)
3774             VG_(printf)("------ new CIE (#%d of 0 .. %d) ------\n",
3775                         n_CIEs, N_CIEs - 1);
3776 
3777 	 /* Allocate a new CIE record. */
3778          vg_assert(n_CIEs >= 0 && n_CIEs <= N_CIEs);
3779          if (n_CIEs == N_CIEs) {
3780             how = "N_CIEs is too low.  Increase and recompile.";
3781             goto bad;
3782          }
3783 
3784          this_CIE = n_CIEs;
3785          n_CIEs++;
3786          init_CIE( &the_CIEs[this_CIE] );
3787 
3788 	 /* Record its offset.  This is how we will find it again
3789             later when looking at an FDE. */
3790          the_CIEs[this_CIE].offset = (ULong)(ciefde_start - frame_image);
3791 
3792          if (di->ddump_frames)
3793             VG_(printf)("%08lx %08lx %08lx CIE\n",
3794                         ((Addr)ciefde_start) - ((Addr)frame_image),
3795                         (Addr)ciefde_len,
3796                         (Addr)(UWord)cie_pointer );
3797 
3798          cie_version = read_UChar(data); data += sizeof(UChar);
3799          if (di->trace_cfi)
3800             VG_(printf)("cie.version     = %d\n", (Int)cie_version);
3801          if (di->ddump_frames)
3802             VG_(printf)("  Version:               %d\n", (Int)cie_version);
3803          if (cie_version != 1 && cie_version != 3 && cie_version != 4) {
3804             how = "unexpected CIE version (not 1 nor 3 nor 4)";
3805             goto bad;
3806          }
3807 
3808          cie_augmentation = data;
3809          data += 1 + VG_(strlen)(cie_augmentation);
3810          if (di->trace_cfi)
3811             VG_(printf)("cie.augment     = \"%s\"\n", cie_augmentation);
3812          if (di->ddump_frames)
3813             VG_(printf)("  Augmentation:          \"%s\"\n", cie_augmentation);
3814 
3815          if (cie_augmentation[0] == 'e' && cie_augmentation[1] == 'h') {
3816             data += sizeof(Addr);
3817             cie_augmentation += 2;
3818          }
3819 
3820          if (cie_version >= 4) {
3821             if (read_UChar(data) != sizeof(Addr)) {
3822                how = "unexpected address size";
3823                goto bad;
3824             }
3825             data += sizeof(UChar);
3826             if (read_UChar(data) != 0) {
3827                how = "unexpected non-zero segment size";
3828                goto bad;
3829             }
3830             data += sizeof(UChar);
3831          }
3832 
3833          the_CIEs[this_CIE].code_a_f = read_leb128( data, &nbytes, 0);
3834          data += nbytes;
3835          if (di->trace_cfi)
3836             VG_(printf)("cie.code_af     = %d\n",
3837                         the_CIEs[this_CIE].code_a_f);
3838          if (di->ddump_frames)
3839             VG_(printf)("  Code alignment factor: %d\n",
3840                         (Int)the_CIEs[this_CIE].code_a_f);
3841 
3842          the_CIEs[this_CIE].data_a_f = read_leb128( data, &nbytes, 1);
3843          data += nbytes;
3844          if (di->trace_cfi)
3845             VG_(printf)("cie.data_af     = %d\n",
3846                         the_CIEs[this_CIE].data_a_f);
3847          if (di->ddump_frames)
3848             VG_(printf)("  Data alignment factor: %d\n",
3849                         (Int)the_CIEs[this_CIE].data_a_f);
3850 
3851          if (cie_version == 1) {
3852             the_CIEs[this_CIE].ra_reg = (Int)read_UChar(data);
3853             data += sizeof(UChar);
3854          } else {
3855             the_CIEs[this_CIE].ra_reg = read_leb128( data, &nbytes, 0);
3856             data += nbytes;
3857          }
3858          if (di->trace_cfi)
3859             VG_(printf)("cie.ra_reg      = %d\n",
3860                         the_CIEs[this_CIE].ra_reg);
3861          if (di->ddump_frames)
3862             VG_(printf)("  Return address column: %d\n",
3863                         (Int)the_CIEs[this_CIE].ra_reg);
3864 
3865          if (the_CIEs[this_CIE].ra_reg < 0
3866              || the_CIEs[this_CIE].ra_reg >= N_CFI_REGS) {
3867             how = "cie.ra_reg has implausible value";
3868             goto bad;
3869          }
3870 
3871          the_CIEs[this_CIE].saw_z_augmentation
3872             = *cie_augmentation == 'z';
3873          if (the_CIEs[this_CIE].saw_z_augmentation) {
3874             UInt length = read_leb128( data, &nbytes, 0);
3875             data += nbytes;
3876             the_CIEs[this_CIE].instrs = data + length;
3877             cie_augmentation++;
3878             if (di->ddump_frames) {
3879                UInt i;
3880                VG_(printf)("  Augmentation data:    ");
3881                for (i = 0; i < length; i++)
3882                   VG_(printf)(" %02x", (UInt)data[i]);
3883                VG_(printf)("\n");
3884             }
3885          } else {
3886             the_CIEs[this_CIE].instrs = NULL;
3887          }
3888 
3889          the_CIEs[this_CIE].address_encoding = default_Addr_encoding();
3890 
3891          while (*cie_augmentation) {
3892             switch (*cie_augmentation) {
3893                case 'L':
3894                   data++;
3895                   cie_augmentation++;
3896                   break;
3897                case 'R':
3898                   the_CIEs[this_CIE].address_encoding
3899                      = read_UChar(data); data += sizeof(UChar);
3900                   cie_augmentation++;
3901                   break;
3902                case 'P':
3903                   data += size_of_encoded_Addr( read_UChar(data) );
3904                   data++;
3905                   cie_augmentation++;
3906                   break;
3907                case 'S':
3908                   cie_augmentation++;
3909                   break;
3910                default:
3911                   if (the_CIEs[this_CIE].instrs == NULL) {
3912                      how = "unhandled cie.augmentation";
3913                      goto bad;
3914                   }
3915                   data = the_CIEs[this_CIE].instrs;
3916                   goto done_augmentation;
3917             }
3918          }
3919 
3920         done_augmentation:
3921 
3922          if (di->trace_cfi)
3923             VG_(printf)("cie.encoding    = 0x%x\n",
3924                         the_CIEs[this_CIE].address_encoding);
3925 
3926          the_CIEs[this_CIE].instrs = data;
3927          the_CIEs[this_CIE].ilen
3928             = ciefde_start + ciefde_len + sizeof(UInt) - data;
3929          if (di->trace_cfi) {
3930             VG_(printf)("cie.instrs      = %p\n", the_CIEs[this_CIE].instrs);
3931             VG_(printf)("cie.ilen        = %d\n", the_CIEs[this_CIE].ilen);
3932 	 }
3933 
3934          if (the_CIEs[this_CIE].ilen < 0
3935              || the_CIEs[this_CIE].ilen > frame_size) {
3936             how = "implausible # cie initial insns";
3937             goto bad;
3938          }
3939 
3940          data += the_CIEs[this_CIE].ilen;
3941 
3942          /* Show the CIE's instructions (the preamble for each FDE
3943             that uses this CIE). */
3944          if (di->ddump_frames)
3945             VG_(printf)("\n");
3946 
3947          if (di->trace_cfi || di->ddump_frames) {
3948             AddressDecodingInfo adi;
3949             adi.encoding      = the_CIEs[this_CIE].address_encoding;
3950             adi.ehframe_image = frame_image;
3951             adi.ehframe_avma  = frame_avma;
3952             adi.text_bias     = di->text_debug_bias;
3953             show_CF_instructions( the_CIEs[this_CIE].instrs,
3954                                   the_CIEs[this_CIE].ilen, &adi,
3955                                   the_CIEs[this_CIE].code_a_f,
3956                                   the_CIEs[this_CIE].data_a_f );
3957          }
3958 
3959          if (di->ddump_frames)
3960             VG_(printf)("\n");
3961 
3962       } else {
3963 
3964          AddressDecodingInfo adi;
3965          UnwindContext ctx, restore_ctx;
3966          Int    cie;
3967          ULong  look_for;
3968          Bool   ok;
3969          Addr   fde_initloc;
3970          UWord  fde_arange;
3971          UChar* fde_instrs;
3972          Int    fde_ilen;
3973 
3974          /* --------- FDE --------- */
3975 
3976          /* Find the relevant CIE.  The CIE we want is located
3977             cie_pointer bytes back from here. */
3978 
3979          /* re sizeof(UInt) / sizeof(ULong), matches XXX above. */
3980          if (for_eh)
3981             look_for = (data - (dw64 ? sizeof(ULong) : sizeof(UInt))
3982                              - frame_image)
3983                        - cie_pointer;
3984          else
3985             look_for = cie_pointer;
3986 
3987          for (cie = 0; cie < n_CIEs; cie++) {
3988             if (0) VG_(printf)("look for %lld   %lld\n",
3989                                look_for, the_CIEs[cie].offset );
3990             if (the_CIEs[cie].offset == look_for)
3991                break;
3992 	 }
3993          vg_assert(cie >= 0 && cie <= n_CIEs);
3994          if (cie == n_CIEs) {
3995             how = "FDE refers to not-findable CIE";
3996             goto bad;
3997 	 }
3998 
3999          adi.encoding      = the_CIEs[cie].address_encoding;
4000          adi.ehframe_image = frame_image;
4001          adi.ehframe_avma  = frame_avma;
4002          adi.text_bias     = di->text_debug_bias;
4003          fde_initloc = read_encoded_Addr(&nbytes, &adi, data);
4004          data += nbytes;
4005          if (di->trace_cfi)
4006             VG_(printf)("fde.initloc     = %#lx\n", fde_initloc);
4007 
4008          adi.encoding      = the_CIEs[cie].address_encoding & 0xf;
4009          adi.ehframe_image = frame_image;
4010          adi.ehframe_avma  = frame_avma;
4011          adi.text_bias     = di->text_debug_bias;
4012 
4013          /* WAS (incorrectly):
4014             fde_arange = read_encoded_Addr(&nbytes, &adi, data);
4015             data += nbytes;
4016             The following corresponds to what binutils/dwarf.c does:
4017          */
4018          { UInt ptr_size = size_of_encoded_Addr( adi.encoding );
4019            switch (ptr_size) {
4020               case 8: case 4: case 2: case 1:
4021                  fde_arange
4022                     = (UWord)read_le_u_encoded_literal(data, ptr_size);
4023                  data += ptr_size;
4024                  break;
4025               default:
4026                  how = "unknown arange field encoding in FDE";
4027                  goto bad;
4028            }
4029          }
4030 
4031          if (di->trace_cfi)
4032             VG_(printf)("fde.arangec     = %#lx\n", fde_arange);
4033 
4034          if (di->ddump_frames)
4035             VG_(printf)("%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
4036                         ((Addr)ciefde_start) - ((Addr)frame_image),
4037                         (Addr)ciefde_len,
4038                         (Addr)(UWord)cie_pointer,
4039                         (Addr)look_for,
4040                         ((Addr)fde_initloc) - di->text_debug_bias,
4041                         ((Addr)fde_initloc) - di->text_debug_bias + fde_arange);
4042 
4043          if (the_CIEs[cie].saw_z_augmentation) {
4044             UInt length = read_leb128( data, &nbytes, 0);
4045             data += nbytes;
4046             if (di->ddump_frames && (length > 0)) {
4047                UInt i;
4048                VG_(printf)("  Augmentation data:    ");
4049                for (i = 0; i < length; i++)
4050                   VG_(printf)(" %02x", (UInt)data[i]);
4051                VG_(printf)("\n\n");
4052             }
4053             data += length;
4054          }
4055 
4056          fde_instrs = data;
4057          fde_ilen   = ciefde_start + ciefde_len + sizeof(UInt) - data;
4058          if (di->trace_cfi) {
4059             VG_(printf)("fde.instrs      = %p\n", fde_instrs);
4060             VG_(printf)("fde.ilen        = %d\n", (Int)fde_ilen);
4061 	 }
4062 
4063          if (fde_ilen < 0 || fde_ilen > frame_size) {
4064             how = "implausible # fde insns";
4065             goto bad;
4066          }
4067 
4068 	 data += fde_ilen;
4069 
4070          if (ehframe_cfsis) {
4071             Addr a_mid_lo, a_mid_hi;
4072             Word mid, size,
4073                  lo = 0,
4074                  hi = ehframe_cfsis-1;
4075             while (True) {
4076                /* current unsearched space is from lo to hi, inclusive. */
4077                if (lo > hi) break; /* not found */
4078                mid      = (lo + hi) / 2;
4079                a_mid_lo = di->cfsi[mid].base;
4080                size     = di->cfsi[mid].len;
4081                a_mid_hi = a_mid_lo + size - 1;
4082                vg_assert(a_mid_hi >= a_mid_lo);
4083                if (fde_initloc + fde_arange <= a_mid_lo) {
4084                   hi = mid-1; continue;
4085                }
4086                if (fde_initloc > a_mid_hi) { lo = mid+1; continue; }
4087                break;
4088             }
4089 
4090             /* The range this .debug_frame FDE covers has been already
4091                covered in .eh_frame section.  Don't add it from .debug_frame
4092                section again.  */
4093             if (lo <= hi)
4094                continue;
4095          }
4096 
4097          adi.encoding      = the_CIEs[cie].address_encoding;
4098          adi.ehframe_image = frame_image;
4099          adi.ehframe_avma  = frame_avma;
4100          adi.text_bias     = di->text_debug_bias;
4101 
4102          if (di->trace_cfi)
4103             show_CF_instructions( fde_instrs, fde_ilen, &adi,
4104                                   the_CIEs[cie].code_a_f,
4105                                   the_CIEs[cie].data_a_f );
4106 
4107 	 initUnwindContext(&ctx);
4108          ctx.code_a_f = the_CIEs[cie].code_a_f;
4109          ctx.data_a_f = the_CIEs[cie].data_a_f;
4110          ctx.initloc  = fde_initloc;
4111          ctx.ra_reg   = the_CIEs[cie].ra_reg;
4112          ctx.exprs    = VG_(newXA)( ML_(dinfo_zalloc), "di.rcid.1",
4113                                     ML_(dinfo_free),
4114                                     sizeof(CfiExpr) );
4115          vg_assert(ctx.exprs);
4116 
4117 	 /* Run the CIE's instructions.  Ugly hack: if
4118             --debug-dump=frames is in effect, suppress output for
4119             these instructions since they will already have been shown
4120             at the time the CIE was first encountered.  Note, not
4121             thread safe - if this reader is ever made threaded, should
4122             fix properly. */
4123 	 { Bool hack = di->ddump_frames;
4124            di->ddump_frames = False;
4125            initUnwindContext(&restore_ctx);
4126            ok = run_CF_instructions(
4127                    di, False, &ctx, the_CIEs[cie].instrs,
4128                    the_CIEs[cie].ilen, 0, NULL, &adi
4129                 );
4130            di->ddump_frames = hack;
4131          }
4132          /* And now run the instructions for the FDE, starting from
4133             the state created by running the CIE preamble
4134             instructions. */
4135          if (ok) {
4136             restore_ctx = ctx;
4137 	    ok = run_CF_instructions(
4138                     di, True, &ctx, fde_instrs, fde_ilen, fde_arange,
4139                     &restore_ctx, &adi
4140                  );
4141             if (di->ddump_frames)
4142                VG_(printf)("\n");
4143 	 }
4144 
4145          VG_(deleteXA)( ctx.exprs );
4146       }
4147    }
4148 
4149    return;
4150 
4151    bad:
4152     if (!VG_(clo_xml) && VG_(clo_verbosity) > 1)
4153        VG_(message)(Vg_UserMsg,
4154                     "Warning: %s in DWARF2 CFI reading\n", how);
4155     return;
4156 }
4157 
4158 #endif // defined(VGO_linux) || defined(VGO_darwin)
4159 
4160 /*--------------------------------------------------------------------*/
4161 /*--- end                                                          ---*/
4162 /*--------------------------------------------------------------------*/
4163