Jakub Jelinek 21fc84
--- valgrind-3.7.0/memcheck/tests/Makefile.am	(revision 12490)
Jakub Jelinek 21fc84
+++ valgrind-3.7.0/memcheck/tests/Makefile.am	(revision 12491)
Jakub Jelinek 21fc84
@@ -76,6 +76,7 @@ EXTRA_DIST = \
Jakub Jelinek 21fc84
 	deep_templates.stdout.exp deep_templates.stderr.exp \
Jakub Jelinek 21fc84
 	describe-block.stderr.exp describe-block.vgtest \
Jakub Jelinek 21fc84
 	doublefree.stderr.exp doublefree.vgtest \
Jakub Jelinek 21fc84
+	dw4.vgtest dw4.stderr.exp dw4.stdout.exp \
Jakub Jelinek 21fc84
 	err_disable1.vgtest err_disable1.stderr.exp \
Jakub Jelinek 21fc84
 	err_disable2.vgtest err_disable2.stderr.exp \
Jakub Jelinek 21fc84
 	err_disable3.vgtest err_disable3.stderr.exp \
Jakub Jelinek 21fc84
@@ -281,6 +282,9 @@ check_PROGRAMS = \
Jakub Jelinek 21fc84
 	wrap1 wrap2 wrap3 wrap4 wrap5 wrap6 wrap7 wrap7so.so wrap8 \
Jakub Jelinek 21fc84
 	writev1
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
+if DWARF4
Jakub Jelinek 21fc84
+check_PROGRAMS += dw4
Jakub Jelinek 21fc84
+endif
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
 AM_CFLAGS   += $(AM_FLAG_M3264_PRI)
Jakub Jelinek 21fc84
 AM_CXXFLAGS += $(AM_FLAG_M3264_PRI)
Jakub Jelinek 21fc84
@@ -299,6 +303,8 @@ endif
Jakub Jelinek 21fc84
 deep_templates_SOURCES	= deep_templates.cpp
Jakub Jelinek 21fc84
 deep_templates_CXXFLAGS	= $(AM_CFLAGS) -O -gstabs
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
+dw4_CFLAGS		= $(AM_CFLAGS) -gdwarf-4 -fdebug-types-section
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
 err_disable3_LDADD 	= -lpthread
Jakub Jelinek 21fc84
 err_disable4_LDADD 	= -lpthread
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
--- valgrind-3.7.0/memcheck/tests/dw4.c	(revision 0)
Jakub Jelinek 21fc84
+++ valgrind-3.7.0/memcheck/tests/dw4.c	(revision 12491)
Jakub Jelinek 21fc84
@@ -0,0 +1,54 @@
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+/* Check of variable location identification when using .debug_types.  */
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+/* Relevant compile flags are:
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+   -Wall -g -I$prefix/include/valgrind -gdwarf-4 -fdebug-types-section
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+   eg -Wall -g -I`pwd`/Inst/include/valgrind -gdwarf-4 -fdebug-types-section
Jakub Jelinek 21fc84
+*/
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+#include <stdio.h>
Jakub Jelinek 21fc84
+#include <stdlib.h>
Jakub Jelinek 21fc84
+#include <assert.h>
Jakub Jelinek 21fc84
+#include "memcheck/memcheck.h"
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+/* Cause memcheck to complain about the address "a" and so to print
Jakub Jelinek 21fc84
+   its best guess as to what "a" actually is.  a must be
Jakub Jelinek 21fc84
+   addressible. */
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+void croak ( void* aV )
Jakub Jelinek 21fc84
+{
Jakub Jelinek 21fc84
+  char* a = (char*)aV;
Jakub Jelinek 21fc84
+  char* undefp = malloc(1);
Jakub Jelinek 21fc84
+  char saved = *a;
Jakub Jelinek 21fc84
+  assert(undefp);
Jakub Jelinek 21fc84
+  *a = *undefp;
Jakub Jelinek 21fc84
+  VALGRIND_CHECK_MEM_IS_DEFINED(a, 1);
Jakub Jelinek 21fc84
+  *a = saved;
Jakub Jelinek 21fc84
+  free(undefp);
Jakub Jelinek 21fc84
+}
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+struct s1
Jakub Jelinek 21fc84
+{
Jakub Jelinek 21fc84
+  char c;
Jakub Jelinek 21fc84
+  short s;
Jakub Jelinek 21fc84
+  int i;
Jakub Jelinek 21fc84
+  long l;
Jakub Jelinek 21fc84
+  float f;
Jakub Jelinek 21fc84
+  double d;
Jakub Jelinek 21fc84
+};
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+struct s1 S2[30];
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+int main ( void )
Jakub Jelinek 21fc84
+{
Jakub Jelinek 21fc84
+  struct s1 local;
Jakub Jelinek 21fc84
+  struct s1* onheap = malloc(sizeof (struct s1));
Jakub Jelinek 21fc84
+  assert(onheap);
Jakub Jelinek 21fc84
+  croak(&onheap->i);
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+  croak( &S2[0].i );
Jakub Jelinek 21fc84
+  croak( &local.i );
Jakub Jelinek 21fc84
+  return 0;
Jakub Jelinek 21fc84
+}
Jakub Jelinek 21fc84
--- valgrind-3.7.0/memcheck/tests/dw4.stderr.exp	(revision 0)
Jakub Jelinek 21fc84
+++ valgrind-3.7.0/memcheck/tests/dw4.stderr.exp	(revision 12491)
Jakub Jelinek 21fc84
@@ -0,0 +1,19 @@
Jakub Jelinek 21fc84
+Uninitialised byte(s) found during client check request
Jakub Jelinek 21fc84
+   at 0x........: croak (dw4.c:27)
Jakub Jelinek 21fc84
+   by 0x........: main (dw4.c:49)
Jakub Jelinek 21fc84
+ Address 0x........ is 4 bytes inside a block of size 32 alloc'd
Jakub Jelinek 21fc84
+   at 0x........: malloc (vg_replace_malloc.c:...)
Jakub Jelinek 21fc84
+   by 0x........: main (dw4.c:47)
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+Uninitialised byte(s) found during client check request
Jakub Jelinek 21fc84
+   at 0x........: croak (dw4.c:27)
Jakub Jelinek 21fc84
+   by 0x........: main (dw4.c:51)
Jakub Jelinek 21fc84
+ Location 0x........ is 0 bytes inside S2[0].i,
Jakub Jelinek 21fc84
+ a global variable declared at dw4.c:42
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+Uninitialised byte(s) found during client check request
Jakub Jelinek 21fc84
+   at 0x........: croak (dw4.c:27)
Jakub Jelinek 21fc84
+   by 0x........: main (dw4.c:52)
Jakub Jelinek 21fc84
+ Location 0x........ is 0 bytes inside local.i,
Jakub Jelinek 21fc84
+ declared at dw4.c:46, in frame #1 of thread 1
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
--- valgrind-3.7.0/memcheck/tests/dw4.vgtest	(revision 0)
Jakub Jelinek 21fc84
+++ valgrind-3.7.0/memcheck/tests/dw4.vgtest	(revision 12491)
Jakub Jelinek 21fc84
@@ -0,0 +1,2 @@
Jakub Jelinek 21fc84
+prog: dw4
Jakub Jelinek 21fc84
+vgopts: --read-var-info=yes -q
Jakub Jelinek 21fc84
--- valgrind-3.7.0/configure.in	(revision 12490)
Jakub Jelinek 21fc84
+++ valgrind-3.7.0/configure.in	(revision 12491)
Jakub Jelinek 21fc84
@@ -1453,6 +1453,26 @@ AC_MSG_RESULT([no])
Jakub Jelinek 21fc84
 CFLAGS=$safe_CFLAGS
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
+# does this compiler support -gdwarf-4 -fdebug-types-section ?
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+AC_MSG_CHECKING([if gcc accepts -gdwarf-4 -fdebug-types-section])
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+safe_CFLAGS=$CFLAGS
Jakub Jelinek 21fc84
+CFLAGS="-gdwarf-4 -fdebug-types-section"
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ ]], [[
Jakub Jelinek 21fc84
+  return 0;
Jakub Jelinek 21fc84
+]])], [
Jakub Jelinek 21fc84
+ac_have_dwarf4=yes
Jakub Jelinek 21fc84
+AC_MSG_RESULT([yes])
Jakub Jelinek 21fc84
+], [
Jakub Jelinek 21fc84
+ac_have_dwarf4=no
Jakub Jelinek 21fc84
+AC_MSG_RESULT([no])
Jakub Jelinek 21fc84
+])
Jakub Jelinek 21fc84
+AM_CONDITIONAL(DWARF4, test x$ac_have_dwarf4 = xyes)
Jakub Jelinek 21fc84
+CFLAGS=$safe_CFLAGS
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
 # does the linker support -Wl,--build-id=none ?  Note, it's
Jakub Jelinek 21fc84
 # important that we test indirectly via whichever C compiler
Jakub Jelinek 21fc84
 # is selected, rather than testing /usr/bin/ld or whatever
Jakub Jelinek 21fc84
--- valgrind-3.7.0/coregrind/m_debuginfo/readdwarf.c	(revision 12490)
Jakub Jelinek 21fc84
+++ valgrind-3.7.0/coregrind/m_debuginfo/readdwarf.c	(revision 12491)
Jakub Jelinek 21fc84
@@ -1166,6 +1166,7 @@ void read_unitinfo_dwarf2( /*OUT*/UnitIn
Jakub Jelinek 21fc84
 void ML_(read_debuginfo_dwarf3)
Jakub Jelinek 21fc84
         ( struct _DebugInfo* di,
Jakub Jelinek 21fc84
           UChar* debug_info_img, Word debug_info_sz, /* .debug_info */
Jakub Jelinek 21fc84
+          UChar* debug_types_img, Word debug_types_sz, /* .debug_types */
Jakub Jelinek 21fc84
           UChar* debug_abbv_img, Word debug_abbv_sz, /* .debug_abbrev */
Jakub Jelinek 21fc84
           UChar* debug_line_img, Word debug_line_sz, /* .debug_line */
Jakub Jelinek 21fc84
           UChar* debug_str_img,  Word debug_str_sz ) /* .debug_str */
Jakub Jelinek 21fc84
--- valgrind-3.7.0/coregrind/m_debuginfo/readelf.c	(revision 12490)
Jakub Jelinek 21fc84
+++ valgrind-3.7.0/coregrind/m_debuginfo/readelf.c	(revision 12491)
Jakub Jelinek 21fc84
@@ -2072,6 +2072,7 @@ Bool ML_(read_elf_debug_info) ( struct _
Jakub Jelinek 21fc84
       UChar*     stabstr_img      = NULL; /* .stabstr      (stabs)  */
Jakub Jelinek 21fc84
       UChar*     debug_line_img   = NULL; /* .debug_line   (dwarf2) */
Jakub Jelinek 21fc84
       UChar*     debug_info_img   = NULL; /* .debug_info   (dwarf2) */
Jakub Jelinek 21fc84
+      UChar*     debug_types_img  = NULL; /* .debug_types  (dwarf4) */
Jakub Jelinek 21fc84
       UChar*     debug_abbv_img   = NULL; /* .debug_abbrev (dwarf2) */
Jakub Jelinek 21fc84
       UChar*     debug_str_img    = NULL; /* .debug_str    (dwarf2) */
Jakub Jelinek 21fc84
       UChar*     debug_ranges_img = NULL; /* .debug_ranges (dwarf2) */
Jakub Jelinek 21fc84
@@ -2093,6 +2094,7 @@ Bool ML_(read_elf_debug_info) ( struct _
Jakub Jelinek 21fc84
       SizeT      stabstr_sz      = 0;
Jakub Jelinek 21fc84
       SizeT      debug_line_sz   = 0;
Jakub Jelinek 21fc84
       SizeT      debug_info_sz   = 0;
Jakub Jelinek 21fc84
+      SizeT      debug_types_sz   = 0;
Jakub Jelinek 21fc84
       SizeT      debug_abbv_sz   = 0;
Jakub Jelinek 21fc84
       SizeT      debug_str_sz    = 0;
Jakub Jelinek 21fc84
       SizeT      debug_ranges_sz = 0;
Jakub Jelinek 21fc84
@@ -2168,6 +2170,7 @@ Bool ML_(read_elf_debug_info) ( struct _
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
          FIND(".debug_line",    debug_line_sz,   debug_line_img)
Jakub Jelinek 21fc84
          FIND(".debug_info",    debug_info_sz,   debug_info_img)
Jakub Jelinek 21fc84
+         FIND(".debug_types",   debug_types_sz,  debug_types_img)
Jakub Jelinek 21fc84
          FIND(".debug_abbrev",  debug_abbv_sz,   debug_abbv_img)
Jakub Jelinek 21fc84
          FIND(".debug_str",     debug_str_sz,    debug_str_img)
Jakub Jelinek 21fc84
          FIND(".debug_ranges",  debug_ranges_sz, debug_ranges_img)
Jakub Jelinek 21fc84
@@ -2425,6 +2428,8 @@ Bool ML_(read_elf_debug_info) ( struct _
Jakub Jelinek 21fc84
             FIND(need_stabs,  ".stabstr",      stabstr_sz,    stabstr_img)
Jakub Jelinek 21fc84
             FIND(need_dwarf2, ".debug_line",   debug_line_sz, debug_line_img)
Jakub Jelinek 21fc84
             FIND(need_dwarf2, ".debug_info",   debug_info_sz, debug_info_img)
Jakub Jelinek 21fc84
+            FIND(need_dwarf2, ".debug_types",  debug_types_sz,
Jakub Jelinek 21fc84
+		                                            debug_types_img)
Jakub Jelinek 21fc84
             FIND(need_dwarf2, ".debug_abbrev", debug_abbv_sz, debug_abbv_img)
Jakub Jelinek 21fc84
             FIND(need_dwarf2, ".debug_str",    debug_str_sz,  debug_str_img)
Jakub Jelinek 21fc84
             FIND(need_dwarf2, ".debug_ranges", debug_ranges_sz, 
Jakub Jelinek 21fc84
@@ -2516,6 +2521,7 @@ Bool ML_(read_elf_debug_info) ( struct _
Jakub Jelinek 21fc84
          /* The old reader: line numbers and unwind info only */
Jakub Jelinek 21fc84
          ML_(read_debuginfo_dwarf3) ( di,
Jakub Jelinek 21fc84
                                       debug_info_img, debug_info_sz,
Jakub Jelinek 21fc84
+                                      debug_types_img, debug_types_sz,
Jakub Jelinek 21fc84
                                       debug_abbv_img, debug_abbv_sz,
Jakub Jelinek 21fc84
                                       debug_line_img, debug_line_sz,
Jakub Jelinek 21fc84
                                       debug_str_img,  debug_str_sz );
Jakub Jelinek 21fc84
@@ -2528,6 +2534,7 @@ Bool ML_(read_elf_debug_info) ( struct _
Jakub Jelinek 21fc84
              || VG_(clo_read_var_info) /* the user asked for it */) {
Jakub Jelinek 21fc84
             ML_(new_dwarf3_reader)(
Jakub Jelinek 21fc84
                di, debug_info_img,   debug_info_sz,
Jakub Jelinek 21fc84
+                   debug_types_img,   debug_types_sz,
Jakub Jelinek 21fc84
                    debug_abbv_img,   debug_abbv_sz,
Jakub Jelinek 21fc84
                    debug_line_img,   debug_line_sz,
Jakub Jelinek 21fc84
                    debug_str_img,    debug_str_sz,
Jakub Jelinek 21fc84
--- valgrind-3.7.0/coregrind/m_debuginfo/priv_readdwarf.h	(revision 12490)
Jakub Jelinek 21fc84
+++ valgrind-3.7.0/coregrind/m_debuginfo/priv_readdwarf.h	(revision 12491)
Jakub Jelinek 21fc84
@@ -45,6 +45,7 @@ extern
Jakub Jelinek 21fc84
 void ML_(read_debuginfo_dwarf3)
Jakub Jelinek 21fc84
         ( struct _DebugInfo* di,
Jakub Jelinek 21fc84
           UChar* debug_info_img, Word debug_info_sz,  /* .debug_info */
Jakub Jelinek 21fc84
+          UChar* debug_types_img, Word debug_types_sz,  /* .debug_types */
Jakub Jelinek 21fc84
           UChar* debug_abbv_img, Word debug_abbv_sz,  /* .debug_abbrev */
Jakub Jelinek 21fc84
           UChar* debug_line_img, Word debug_line_sz,  /* .debug_line */
Jakub Jelinek 21fc84
           UChar* debug_str_img,  Word debug_str_sz ); /* .debug_str */
Jakub Jelinek 21fc84
--- valgrind-3.7.0/coregrind/m_debuginfo/readdwarf3.c	(revision 12490)
Jakub Jelinek 21fc84
+++ valgrind-3.7.0/coregrind/m_debuginfo/readdwarf3.c	(revision 12491)
Jakub Jelinek 21fc84
@@ -140,6 +140,7 @@
Jakub Jelinek 21fc84
 #include "pub_core_libcassert.h"
Jakub Jelinek 21fc84
 #include "pub_core_libcprint.h"
Jakub Jelinek 21fc84
 #include "pub_core_libcsetjmp.h"   // setjmp facilities
Jakub Jelinek 21fc84
+#include "pub_core_hashtable.h"
Jakub Jelinek 21fc84
 #include "pub_core_options.h"
Jakub Jelinek 21fc84
 #include "pub_core_tooliface.h"    /* VG_(needs) */
Jakub Jelinek 21fc84
 #include "pub_core_xarray.h"
Jakub Jelinek 21fc84
@@ -415,6 +416,9 @@ typedef
Jakub Jelinek 21fc84
       /* Where is .debug_info? */
Jakub Jelinek 21fc84
       UChar* debug_info_img;
Jakub Jelinek 21fc84
       UWord  debug_info_sz;
Jakub Jelinek 21fc84
+      /* Where is .debug_types? */
Jakub Jelinek 21fc84
+      UChar* debug_types_img;
Jakub Jelinek 21fc84
+      UWord  debug_types_sz;
Jakub Jelinek 21fc84
       /* --- Needed so we can add stuff to the string table. --- */
Jakub Jelinek 21fc84
       struct _DebugInfo* di;
Jakub Jelinek 21fc84
       /* --- a cache for set_abbv_Cursor --- */
Jakub Jelinek 21fc84
@@ -422,10 +426,57 @@ typedef
Jakub Jelinek 21fc84
       struct { ULong abbv_code; UWord posn; } saC_cache[N_ABBV_CACHE];
Jakub Jelinek 21fc84
       UWord saC_cache_queries;
Jakub Jelinek 21fc84
       UWord saC_cache_misses;
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+      /* True if this came from .debug_types; otherwise it came from
Jakub Jelinek 21fc84
+         .debug_info.  */
Jakub Jelinek 21fc84
+      Bool is_type_unit;
Jakub Jelinek 21fc84
+      /* For a unit coming from .debug_types, these hold the TU's type
Jakub Jelinek 21fc84
+         signature and the uncooked DIE offset of the TU's signatured
Jakub Jelinek 21fc84
+         type.  For a unit coming from .debug_info, these are unused.  */
Jakub Jelinek 21fc84
+      ULong type_signature;
Jakub Jelinek 21fc84
+      ULong type_offset;
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+      /* Signatured type hash; computed once and then shared by all
Jakub Jelinek 21fc84
+         CUs.  */
Jakub Jelinek 21fc84
+      VgHashTable signature_types;
Jakub Jelinek 21fc84
    }
Jakub Jelinek 21fc84
    CUConst;
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
+/* Return the cooked value of DIE depending on whether CC represents a
Jakub Jelinek 21fc84
+   .debug_types unit.  To cook a DIE, we pretend that the .debug_info
Jakub Jelinek 21fc84
+   and .debug_types sections form a contiguous whole, so that DIEs
Jakub Jelinek 21fc84
+   coming from .debug_types are numbered starting at the end of
Jakub Jelinek 21fc84
+   .debug_info.  */
Jakub Jelinek 21fc84
+static UWord cook_die( CUConst* cc, UWord die )
Jakub Jelinek 21fc84
+{
Jakub Jelinek 21fc84
+   if (cc->is_type_unit)
Jakub Jelinek 21fc84
+      die += cc->debug_info_sz;
Jakub Jelinek 21fc84
+   return die;
Jakub Jelinek 21fc84
+}
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+/* Like cook_die, but understand that DIEs coming from a
Jakub Jelinek 21fc84
+   DW_FORM_ref_sig8 reference are already cooked.  */
Jakub Jelinek 21fc84
+static UWord cook_die_using_form( CUConst *cc, UWord die, DW_FORM form)
Jakub Jelinek 21fc84
+{
Jakub Jelinek 21fc84
+   if (form == DW_FORM_ref_sig8)
Jakub Jelinek 21fc84
+      return die;
Jakub Jelinek 21fc84
+   return cook_die( cc, die );
Jakub Jelinek 21fc84
+}
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+/* Return the uncooked offset of DIE and set *FLAG to true if the DIE
Jakub Jelinek 21fc84
+   came from the .debug_types section.  */
Jakub Jelinek 21fc84
+static UWord uncook_die( CUConst *cc, UWord die, /*OUT*/Bool *flag )
Jakub Jelinek 21fc84
+{
Jakub Jelinek 21fc84
+   if (die >= cc->debug_info_sz) {
Jakub Jelinek 21fc84
+      *flag = True;
Jakub Jelinek 21fc84
+      die -= cc->debug_info_sz;
Jakub Jelinek 21fc84
+   } else {
Jakub Jelinek 21fc84
+      *flag = False;
Jakub Jelinek 21fc84
+   }
Jakub Jelinek 21fc84
+   return die;
Jakub Jelinek 21fc84
+}
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
 /*------------------------------------------------------------*/
Jakub Jelinek 21fc84
 /*---                                                      ---*/
Jakub Jelinek 21fc84
 /*--- Helper functions for Guarded Expressions             ---*/
Jakub Jelinek 21fc84
@@ -778,7 +829,8 @@ static __attribute__((noinline))
Jakub Jelinek 21fc84
 void parse_CU_Header ( /*OUT*/CUConst* cc,
Jakub Jelinek 21fc84
                        Bool td3,
Jakub Jelinek 21fc84
                        Cursor* c, 
Jakub Jelinek 21fc84
-                       UChar* debug_abbv_img, UWord debug_abbv_sz )
Jakub Jelinek 21fc84
+                       UChar* debug_abbv_img, UWord debug_abbv_sz,
Jakub Jelinek 21fc84
+		       Bool type_unit )
Jakub Jelinek 21fc84
 {
Jakub Jelinek 21fc84
    UChar  address_size;
Jakub Jelinek 21fc84
    UWord  debug_abbrev_offset;
Jakub Jelinek 21fc84
@@ -816,6 +868,13 @@ void parse_CU_Header ( /*OUT*/CUConst* c
Jakub Jelinek 21fc84
       cc->barf( "parse_CU_Header: invalid address_size" );
Jakub Jelinek 21fc84
    TRACE_D3("   Pointer Size:  %d\n", (Int)address_size );
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
+   cc->is_type_unit = type_unit;
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+   if (type_unit) {
Jakub Jelinek 21fc84
+      cc->type_signature = get_ULong( c );
Jakub Jelinek 21fc84
+      cc->type_offset = get_Dwarfish_UWord( c, cc->is_dw64 );
Jakub Jelinek 21fc84
+   }
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
    /* Set up so that cc->debug_abbv points to the relevant table for
Jakub Jelinek 21fc84
       this CU.  Set the szB so that at least we can't read off the end
Jakub Jelinek 21fc84
       of the debug_abbrev section -- potentially (and quite likely)
Jakub Jelinek 21fc84
@@ -926,6 +985,50 @@ void set_abbv_Cursor ( /*OUT*/Cursor* c,
Jakub Jelinek 21fc84
    cc->saC_cache[N_ABBV_CACHE/2].posn = get_position_of_Cursor(c);
Jakub Jelinek 21fc84
 }
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
+/* This represents a single signatured type.  It maps a type signature
Jakub Jelinek 21fc84
+   (a ULong) to a cooked DIE offset.  Objects of this type are stored
Jakub Jelinek 21fc84
+   in the type signature hash table.  */
Jakub Jelinek 21fc84
+typedef
Jakub Jelinek 21fc84
+   struct D3SignatureType {
Jakub Jelinek 21fc84
+      struct D3SignatureType *next;
Jakub Jelinek 21fc84
+      UWord data;
Jakub Jelinek 21fc84
+      ULong type_signature;
Jakub Jelinek 21fc84
+      UWord die;
Jakub Jelinek 21fc84
+   }
Jakub Jelinek 21fc84
+   D3SignatureType;
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+/* Record a signatured type in the hash table.  */
Jakub Jelinek 21fc84
+static void record_signatured_type ( VgHashTable tab,
Jakub Jelinek 21fc84
+                                     ULong type_signature,
Jakub Jelinek 21fc84
+                                     UWord die )
Jakub Jelinek 21fc84
+{
Jakub Jelinek 21fc84
+   D3SignatureType *dstype = ML_(dinfo_zalloc) ( "di.readdwarf3.sigtype",
Jakub Jelinek 21fc84
+                                                 sizeof(D3SignatureType) );
Jakub Jelinek 21fc84
+   dstype->data = (UWord) type_signature;
Jakub Jelinek 21fc84
+   dstype->type_signature = type_signature;
Jakub Jelinek 21fc84
+   dstype->die = die;
Jakub Jelinek 21fc84
+   VG_(HT_add_node) ( tab, dstype );
Jakub Jelinek 21fc84
+}
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+/* Given a type signature hash table and a type signature, return the
Jakub Jelinek 21fc84
+   cooked DIE offset of the type.  If the type cannot be found, call
Jakub Jelinek 21fc84
+   BARF.  */
Jakub Jelinek 21fc84
+static UWord lookup_signatured_type ( VgHashTable tab,
Jakub Jelinek 21fc84
+                                      ULong type_signature,
Jakub Jelinek 21fc84
+                                      void (*barf)( HChar* ) __attribute__((noreturn)) )
Jakub Jelinek 21fc84
+{
Jakub Jelinek 21fc84
+   D3SignatureType *dstype = VG_(HT_lookup) ( tab, (UWord) type_signature );
Jakub Jelinek 21fc84
+   /* This may be unwarranted chumminess with the hash table
Jakub Jelinek 21fc84
+      implementation.  */
Jakub Jelinek 21fc84
+   while ( dstype != NULL && dstype->type_signature != type_signature)
Jakub Jelinek 21fc84
+      dstype = dstype->next;
Jakub Jelinek 21fc84
+   if (dstype == NULL) {
Jakub Jelinek 21fc84
+      barf("lookup_signatured_type: could not find signatured type");
Jakub Jelinek 21fc84
+      /*NOTREACHED*/
Jakub Jelinek 21fc84
+      vg_assert(0);
Jakub Jelinek 21fc84
+   }
Jakub Jelinek 21fc84
+   return dstype->die;
Jakub Jelinek 21fc84
+}
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
 /* From 'c', get the Form data into the lowest 1/2/4/8 bytes of *cts.
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
@@ -1164,14 +1267,20 @@ void get_Form_contents ( /*OUT*/ULong* c
Jakub Jelinek 21fc84
       }
Jakub Jelinek 21fc84
       case DW_FORM_ref_sig8: {
Jakub Jelinek 21fc84
          ULong  u64b;
Jakub Jelinek 21fc84
-         UChar* block = get_address_of_Cursor(c);
Jakub Jelinek 21fc84
+         ULong  signature = get_ULong (c);
Jakub Jelinek 21fc84
+         ULong  work = signature;
Jakub Jelinek 21fc84
          TRACE_D3("8 byte signature: ");
Jakub Jelinek 21fc84
          for (u64b = 8; u64b > 0; u64b--) {
Jakub Jelinek 21fc84
-            UChar u8 = get_UChar(c);
Jakub Jelinek 21fc84
+            UChar u8 = work & 0xff;
Jakub Jelinek 21fc84
             TRACE_D3("%x ", (UInt)u8);
Jakub Jelinek 21fc84
+            work >>= 8;
Jakub Jelinek 21fc84
          }
Jakub Jelinek 21fc84
-         *cts = (ULong)(UWord)block;
Jakub Jelinek 21fc84
-         *ctsMemSzB = 8;
Jakub Jelinek 21fc84
+         /* Due to the way that the hash table is constructed, the
Jakub Jelinek 21fc84
+            resulting DIE offset here is already "cooked".  See
Jakub Jelinek 21fc84
+            cook_die_using_form.  */
Jakub Jelinek 21fc84
+         *cts = lookup_signatured_type (cc->signature_types, signature,
Jakub Jelinek 21fc84
+                                        c->barf);
Jakub Jelinek 21fc84
+         *ctsSzB = sizeof(UWord);
Jakub Jelinek 21fc84
          break;
Jakub Jelinek 21fc84
       }
Jakub Jelinek 21fc84
       case DW_FORM_indirect:
Jakub Jelinek 21fc84
@@ -1468,10 +1577,11 @@ static void parse_var_DIE (
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
    UWord saved_die_c_offset  = get_position_of_Cursor( c_die );
Jakub Jelinek 21fc84
    UWord saved_abbv_c_offset = get_position_of_Cursor( c_abbv );
Jakub Jelinek 21fc84
+   Bool  debug_types_flag;
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
    varstack_preen( parser, td3, level-1 );
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
-   if (dtag == DW_TAG_compile_unit) {
Jakub Jelinek 21fc84
+   if (dtag == DW_TAG_compile_unit || dtag == DW_TAG_type_unit) {
Jakub Jelinek 21fc84
       Bool have_lo    = False;
Jakub Jelinek 21fc84
       Bool have_hi1   = False;
Jakub Jelinek 21fc84
       Bool have_range = False;
Jakub Jelinek 21fc84
@@ -1685,7 +1795,7 @@ static void parse_var_DIE (
Jakub Jelinek 21fc84
             VG_(addToXA)(gexprs, &gexpr);
Jakub Jelinek 21fc84
          }
Jakub Jelinek 21fc84
          if (attr == DW_AT_type && ctsSzB > 0) {
Jakub Jelinek 21fc84
-            typeR = (UWord)cts;
Jakub Jelinek 21fc84
+            typeR = cook_die_using_form( cc, (UWord)cts, form );
Jakub Jelinek 21fc84
          }
Jakub Jelinek 21fc84
          if (attr == DW_AT_external && ctsSzB > 0 && cts > 0) {
Jakub Jelinek 21fc84
             external = True;
Jakub Jelinek 21fc84
@@ -1917,7 +2027,12 @@ static void parse_var_DIE (
Jakub Jelinek 21fc84
    set_position_of_Cursor( c_die,  saved_die_c_offset );
Jakub Jelinek 21fc84
    set_position_of_Cursor( c_abbv, saved_abbv_c_offset );
Jakub Jelinek 21fc84
    VG_(printf)("\nparse_var_DIE: confused by:\n");
Jakub Jelinek 21fc84
-   VG_(printf)(" <%d><%lx>: %s\n", level, posn, ML_(pp_DW_TAG)( dtag ) );
Jakub Jelinek 21fc84
+   posn = uncook_die( cc, posn, &debug_types_flag );
Jakub Jelinek 21fc84
+   VG_(printf)(" <%d><%lx>: %s", level, posn, ML_(pp_DW_TAG)( dtag ) );
Jakub Jelinek 21fc84
+   if (debug_types_flag) {
Jakub Jelinek 21fc84
+      VG_(printf)(" (in .debug_types)");
Jakub Jelinek 21fc84
+   }
Jakub Jelinek 21fc84
+   VG_(printf)("\n");
Jakub Jelinek 21fc84
    while (True) {
Jakub Jelinek 21fc84
       DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
Jakub Jelinek 21fc84
       DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
Jakub Jelinek 21fc84
@@ -2097,6 +2212,7 @@ static void parse_type_DIE ( /*MOD*/XArr
Jakub Jelinek 21fc84
    TyEnt atomE;
Jakub Jelinek 21fc84
    TyEnt fieldE;
Jakub Jelinek 21fc84
    TyEnt boundE;
Jakub Jelinek 21fc84
+   Bool  debug_types_flag;
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
    UWord saved_die_c_offset  = get_position_of_Cursor( c_die );
Jakub Jelinek 21fc84
    UWord saved_abbv_c_offset = get_position_of_Cursor( c_abbv );
Jakub Jelinek 21fc84
@@ -2111,7 +2227,7 @@ static void parse_type_DIE ( /*MOD*/XArr
Jakub Jelinek 21fc84
       its children. */
Jakub Jelinek 21fc84
    typestack_preen( parser, td3, level-1 );
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
-   if (dtag == DW_TAG_compile_unit) {
Jakub Jelinek 21fc84
+   if (dtag == DW_TAG_compile_unit || dtag == DW_TAG_type_unit) {
Jakub Jelinek 21fc84
       /* See if we can find DW_AT_language, since it is important for
Jakub Jelinek 21fc84
          establishing array bounds (see DW_TAG_subrange_type below in
Jakub Jelinek 21fc84
          this fn) */
Jakub Jelinek 21fc84
@@ -2272,7 +2388,7 @@ static void parse_type_DIE ( /*MOD*/XArr
Jakub Jelinek 21fc84
             typeE.Te.TyPorR.szB = cts;
Jakub Jelinek 21fc84
          }
Jakub Jelinek 21fc84
          if (attr == DW_AT_type && ctsSzB > 0) {
Jakub Jelinek 21fc84
-            typeE.Te.TyPorR.typeR = (UWord)cts;
Jakub Jelinek 21fc84
+            typeE.Te.TyPorR.typeR = cook_die_using_form( cc, (UWord)cts, form );
Jakub Jelinek 21fc84
          }
Jakub Jelinek 21fc84
       }
Jakub Jelinek 21fc84
       /* Do we have something that looks sane? */
Jakub Jelinek 21fc84
@@ -2317,8 +2433,23 @@ static void parse_type_DIE ( /*MOD*/XArr
Jakub Jelinek 21fc84
           /* we must know the size */
Jakub Jelinek 21fc84
           /* but not for Ada, which uses such dummy
Jakub Jelinek 21fc84
              enumerations as helper for gdb ada mode. */
Jakub Jelinek 21fc84
-          && parser->language != 'A')
Jakub Jelinek 21fc84
-         goto bad_DIE;
Jakub Jelinek 21fc84
+          && parser->language != 'A') {
Jakub Jelinek 21fc84
+         /* GCC has been seen to put an odd DIE like this into
Jakub Jelinek 21fc84
+            .debug_types:
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+            <1><cb72>: DW_TAG_enumeration_type (in .debug_types)
Jakub Jelinek 21fc84
+            DW_AT_name        : (indirect string, offset: 0x3374a): exec_direction_kind
Jakub Jelinek 21fc84
+            DW_AT_declaration : 1	
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+            It isn't clear what this means, but we accept it and
Jakub Jelinek 21fc84
+            assume that the enum is int-sized.  */
Jakub Jelinek 21fc84
+         if (cc->is_type_unit) {
Jakub Jelinek 21fc84
+            typeE.Te.TyEnum.szB = sizeof(int);
Jakub Jelinek 21fc84
+         } else {
Jakub Jelinek 21fc84
+            goto bad_DIE;
Jakub Jelinek 21fc84
+         }
Jakub Jelinek 21fc84
+      }
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
       /* On't stack! */
Jakub Jelinek 21fc84
       typestack_push( cc, parser, td3, &typeE, level );
Jakub Jelinek 21fc84
       goto acquire_Type;
Jakub Jelinek 21fc84
@@ -2487,7 +2618,7 @@ static void parse_type_DIE ( /*MOD*/XArr
Jakub Jelinek 21fc84
                                     (UChar*)(UWord)cts );
Jakub Jelinek 21fc84
          }
Jakub Jelinek 21fc84
          if (attr == DW_AT_type && ctsSzB > 0) {
Jakub Jelinek 21fc84
-            fieldE.Te.Field.typeR = (UWord)cts;
Jakub Jelinek 21fc84
+            fieldE.Te.Field.typeR = cook_die_using_form( cc, (UWord)cts, form );
Jakub Jelinek 21fc84
          }
Jakub Jelinek 21fc84
          /* There are 2 different cases for DW_AT_data_member_location.
Jakub Jelinek 21fc84
             If it is a constant class attribute, it contains byte offset
Jakub Jelinek 21fc84
@@ -2567,7 +2698,8 @@ static void parse_type_DIE ( /*MOD*/XArr
Jakub Jelinek 21fc84
          get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
Jakub Jelinek 21fc84
                             cc, c_die, False/*td3*/, form );
Jakub Jelinek 21fc84
          if (attr == DW_AT_type && ctsSzB > 0) {
Jakub Jelinek 21fc84
-            typeE.Te.TyArray.typeR = (UWord)cts;
Jakub Jelinek 21fc84
+            typeE.Te.TyArray.typeR = cook_die_using_form( cc, (UWord)cts,
Jakub Jelinek 21fc84
+                                                          form );
Jakub Jelinek 21fc84
          }
Jakub Jelinek 21fc84
       }
Jakub Jelinek 21fc84
       if (typeE.Te.TyArray.typeR == D3_INVALID_CUOFF)
Jakub Jelinek 21fc84
@@ -2690,7 +2822,8 @@ static void parse_type_DIE ( /*MOD*/XArr
Jakub Jelinek 21fc84
                                     (UChar*)(UWord)cts );
Jakub Jelinek 21fc84
          }
Jakub Jelinek 21fc84
          if (attr == DW_AT_type && ctsSzB > 0) {
Jakub Jelinek 21fc84
-            typeE.Te.TyTyDef.typeR = (UWord)cts;
Jakub Jelinek 21fc84
+            typeE.Te.TyTyDef.typeR = cook_die_using_form( cc, (UWord)cts,
Jakub Jelinek 21fc84
+                                                          form );
Jakub Jelinek 21fc84
          }
Jakub Jelinek 21fc84
       }
Jakub Jelinek 21fc84
       /* Do we have something that looks sane? */
Jakub Jelinek 21fc84
@@ -2733,7 +2866,7 @@ static void parse_type_DIE ( /*MOD*/XArr
Jakub Jelinek 21fc84
          get_Form_contents( &cts, &ctsSzB, &ctsMemSzB,
Jakub Jelinek 21fc84
                             cc, c_die, False/*td3*/, form );
Jakub Jelinek 21fc84
          if (attr == DW_AT_type && ctsSzB > 0) {
Jakub Jelinek 21fc84
-            typeE.Te.TyQual.typeR = (UWord)cts;
Jakub Jelinek 21fc84
+            typeE.Te.TyQual.typeR = cook_die_using_form( cc, (UWord)cts, form );
Jakub Jelinek 21fc84
             have_ty++;
Jakub Jelinek 21fc84
          }
Jakub Jelinek 21fc84
       }
Jakub Jelinek 21fc84
@@ -2813,7 +2946,12 @@ static void parse_type_DIE ( /*MOD*/XArr
Jakub Jelinek 21fc84
    set_position_of_Cursor( c_die,  saved_die_c_offset );
Jakub Jelinek 21fc84
    set_position_of_Cursor( c_abbv, saved_abbv_c_offset );
Jakub Jelinek 21fc84
    VG_(printf)("\nparse_type_DIE: confused by:\n");
Jakub Jelinek 21fc84
-   VG_(printf)(" <%d><%lx>: %s\n", level, posn, ML_(pp_DW_TAG)( dtag ) );
Jakub Jelinek 21fc84
+   posn = uncook_die( cc, posn, &debug_types_flag );
Jakub Jelinek 21fc84
+   VG_(printf)(" <%d><%lx>: %s", level, posn, ML_(pp_DW_TAG)( dtag ) );
Jakub Jelinek 21fc84
+   if (debug_types_flag) {
Jakub Jelinek 21fc84
+      VG_(printf)(" (in .debug_types)");
Jakub Jelinek 21fc84
+   }
Jakub Jelinek 21fc84
+   VG_(printf)("\n");
Jakub Jelinek 21fc84
    while (True) {
Jakub Jelinek 21fc84
       DW_AT   attr = (DW_AT)  get_ULEB128( c_abbv );
Jakub Jelinek 21fc84
       DW_FORM form = (DW_FORM)get_ULEB128( c_abbv );
Jakub Jelinek 21fc84
@@ -3186,7 +3324,7 @@ static void read_DIE (
Jakub Jelinek 21fc84
    UWord  after_die_c_offset, after_abbv_c_offset;
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
    /* --- Deal with this DIE --- */
Jakub Jelinek 21fc84
-   posn      = get_position_of_Cursor( c );
Jakub Jelinek 21fc84
+   posn      = cook_die( cc, get_position_of_Cursor( c ) );
Jakub Jelinek 21fc84
    abbv_code = get_ULEB128( c );
Jakub Jelinek 21fc84
    set_abbv_Cursor( &abbv, td3, cc, abbv_code );
Jakub Jelinek 21fc84
    atag      = get_ULEB128( &abbv );
Jakub Jelinek 21fc84
@@ -3284,6 +3422,7 @@ void new_dwarf3_reader_wrk (
Jakub Jelinek 21fc84
    struct _DebugInfo* di,
Jakub Jelinek 21fc84
    __attribute__((noreturn)) void (*barf)( HChar* ),
Jakub Jelinek 21fc84
    UChar* debug_info_img,   SizeT debug_info_sz,
Jakub Jelinek 21fc84
+   UChar* debug_types_img,  SizeT debug_types_sz,
Jakub Jelinek 21fc84
    UChar* debug_abbv_img,   SizeT debug_abbv_sz,
Jakub Jelinek 21fc84
    UChar* debug_line_img,   SizeT debug_line_sz,
Jakub Jelinek 21fc84
    UChar* debug_str_img,    SizeT debug_str_sz,
Jakub Jelinek 21fc84
@@ -3310,6 +3449,8 @@ void new_dwarf3_reader_wrk (
Jakub Jelinek 21fc84
    Word  i, j, n;
Jakub Jelinek 21fc84
    Bool td3 = di->trace_symtab;
Jakub Jelinek 21fc84
    XArray* /* of TempVar* */ dioff_lookup_tab;
Jakub Jelinek 21fc84
+   Int pass;
Jakub Jelinek 21fc84
+   VgHashTable signature_types;
Jakub Jelinek 21fc84
 #if 0
Jakub Jelinek 21fc84
    /* This doesn't work properly because it assumes all entries are
Jakub Jelinek 21fc84
       packed end to end, with no holes.  But that doesn't always
Jakub Jelinek 21fc84
@@ -3443,13 +3584,6 @@ void new_dwarf3_reader_wrk (
Jakub Jelinek 21fc84
    }
Jakub Jelinek 21fc84
    TRACE_SYMTAB("\n");
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
-   /* Now loop over the Compilation Units listed in the .debug_info
Jakub Jelinek 21fc84
-      section (see D3SPEC sec 7.5) paras 1 and 2.  Each compilation
Jakub Jelinek 21fc84
-      unit contains a Compilation Unit Header followed by precisely
Jakub Jelinek 21fc84
-      one DW_TAG_compile_unit or DW_TAG_partial_unit DIE. */
Jakub Jelinek 21fc84
-   init_Cursor( &info, debug_info_img, debug_info_sz, 0, barf,
Jakub Jelinek 21fc84
-                "Overrun whilst reading .debug_info section" );
Jakub Jelinek 21fc84
-
Jakub Jelinek 21fc84
    /* We'll park the harvested type information in here.  Also create
Jakub Jelinek 21fc84
       a fake "void" entry with offset D3_FAKEVOID_CUOFF, so we always
Jakub Jelinek 21fc84
       have at least one type entry to refer to.  D3_FAKEVOID_CUOFF is
Jakub Jelinek 21fc84
@@ -3511,158 +3645,234 @@ void new_dwarf3_reader_wrk (
Jakub Jelinek 21fc84
    VG_(memset)( &varparser, 0, sizeof(varparser) );
Jakub Jelinek 21fc84
    varparser.sp = -1;
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
-   TRACE_D3("\n------ Parsing .debug_info section ------\n");
Jakub Jelinek 21fc84
-   while (True) {
Jakub Jelinek 21fc84
-      UWord   cu_start_offset, cu_offset_now;
Jakub Jelinek 21fc84
-      CUConst cc;
Jakub Jelinek 21fc84
-      /* It may be that the stated size of this CU is larger than the
Jakub Jelinek 21fc84
-         amount of stuff actually in it.  icc9 seems to generate CUs
Jakub Jelinek 21fc84
-         thusly.  We use these variables to figure out if this is
Jakub Jelinek 21fc84
-         indeed the case, and if so how many bytes we need to skip to
Jakub Jelinek 21fc84
-         get to the start of the next CU.  Not skipping those bytes
Jakub Jelinek 21fc84
-         causes us to misidentify the start of the next CU, and it all
Jakub Jelinek 21fc84
-         goes badly wrong after that (not surprisingly). */
Jakub Jelinek 21fc84
-      UWord cu_size_including_IniLen, cu_amount_used;
Jakub Jelinek 21fc84
-
Jakub Jelinek 21fc84
-      /* It seems icc9 finishes the DIE info before debug_info_sz
Jakub Jelinek 21fc84
-         bytes have been used up.  So be flexible, and declare the
Jakub Jelinek 21fc84
-         sequence complete if there is not enough remaining bytes to
Jakub Jelinek 21fc84
-         hold even the smallest conceivable CU header.  (11 bytes I
Jakub Jelinek 21fc84
-         reckon). */
Jakub Jelinek 21fc84
-      /* JRS 23Jan09: I suspect this is no longer necessary now that
Jakub Jelinek 21fc84
-         the code below contains a 'while (cu_amount_used <
Jakub Jelinek 21fc84
-         cu_size_including_IniLen ...'  style loop, which skips over
Jakub Jelinek 21fc84
-         any leftover bytes at the end of a CU in the case where the
Jakub Jelinek 21fc84
-         CU's stated size is larger than its actual size (as
Jakub Jelinek 21fc84
-         determined by reading all its DIEs).  However, for prudence,
Jakub Jelinek 21fc84
-         I'll leave the following test in place.  I can't see that a
Jakub Jelinek 21fc84
-         CU header can be smaller than 11 bytes, so I don't think
Jakub Jelinek 21fc84
-         there's any harm possible through the test -- it just adds
Jakub Jelinek 21fc84
-         robustness. */
Jakub Jelinek 21fc84
-      Word avail = get_remaining_length_Cursor( &info );
Jakub Jelinek 21fc84
-      if (avail < 11) {
Jakub Jelinek 21fc84
-         if (avail > 0)
Jakub Jelinek 21fc84
-            TRACE_D3("new_dwarf3_reader_wrk: warning: "
Jakub Jelinek 21fc84
-                     "%ld unused bytes after end of DIEs\n", avail);
Jakub Jelinek 21fc84
-         break;
Jakub Jelinek 21fc84
-      }
Jakub Jelinek 21fc84
+   signature_types = VG_(HT_construct) ("signature_types");
Jakub Jelinek 21fc84
+   
Jakub Jelinek 21fc84
+   /* Do an initial pass to scan the .debug_types section, if any, and
Jakub Jelinek 21fc84
+      fill in the signatured types hash table.  This lets us handle
Jakub Jelinek 21fc84
+      mapping from a type signature to a (cooked) DIE offset directly
Jakub Jelinek 21fc84
+      in get_Form_contents.  */
Jakub Jelinek 21fc84
+   if (debug_types_img != NULL) {
Jakub Jelinek 21fc84
+      init_Cursor( &info, debug_types_img, debug_types_sz, 0, barf,
Jakub Jelinek 21fc84
+                   "Overrun whilst reading .debug_types section" );
Jakub Jelinek 21fc84
+      TRACE_D3("\n------ Collecting signatures from .debug_types section ------\n");
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
-      /* Check the varparser's stack is in a sane state. */
Jakub Jelinek 21fc84
-      vg_assert(varparser.sp == -1);
Jakub Jelinek 21fc84
-      for (i = 0; i < N_D3_VAR_STACK; i++) {
Jakub Jelinek 21fc84
-         vg_assert(varparser.ranges[i] == NULL);
Jakub Jelinek 21fc84
-         vg_assert(varparser.level[i] == 0);
Jakub Jelinek 21fc84
-      }
Jakub Jelinek 21fc84
-      for (i = 0; i < N_D3_TYPE_STACK; i++) {
Jakub Jelinek 21fc84
-         vg_assert(typarser.qparentE[i].cuOff == D3_INVALID_CUOFF);
Jakub Jelinek 21fc84
-         vg_assert(typarser.qparentE[i].tag   == Te_EMPTY);
Jakub Jelinek 21fc84
-         vg_assert(typarser.qlevel[i] == 0);
Jakub Jelinek 21fc84
+      while (True) {
Jakub Jelinek 21fc84
+         UWord   cu_start_offset, cu_offset_now;
Jakub Jelinek 21fc84
+         CUConst cc;
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         cu_start_offset = get_position_of_Cursor( &info );
Jakub Jelinek 21fc84
+         TRACE_D3("\n");
Jakub Jelinek 21fc84
+         TRACE_D3("  Compilation Unit @ offset 0x%lx:\n", cu_start_offset);
Jakub Jelinek 21fc84
+         /* parse_CU_header initialises the CU's set_abbv_Cursor cache
Jakub Jelinek 21fc84
+            (saC_cache) */
Jakub Jelinek 21fc84
+         parse_CU_Header( &cc, td3, &info,
Jakub Jelinek 21fc84
+                          (UChar*)debug_abbv_img, debug_abbv_sz,
Jakub Jelinek 21fc84
+                          True );
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         /* Needed by cook_die.  */
Jakub Jelinek 21fc84
+         cc.debug_info_sz    = debug_info_sz;
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         record_signatured_type( signature_types, cc.type_signature,
Jakub Jelinek 21fc84
+                                 cook_die( &cc, cc.type_offset ));
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         /* Until proven otherwise we assume we don't need the icc9
Jakub Jelinek 21fc84
+            workaround in this case; see the DIE-reading loop below
Jakub Jelinek 21fc84
+            for details.  */
Jakub Jelinek 21fc84
+         cu_offset_now = (cu_start_offset + cc.unit_length
Jakub Jelinek 21fc84
+                          + (cc.is_dw64 ? 12 : 4));
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         if (cu_offset_now == debug_types_sz)
Jakub Jelinek 21fc84
+            break;
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         set_position_of_Cursor ( &info, cu_offset_now );
Jakub Jelinek 21fc84
       }
Jakub Jelinek 21fc84
+   }
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
-      cu_start_offset = get_position_of_Cursor( &info );
Jakub Jelinek 21fc84
-      TRACE_D3("\n");
Jakub Jelinek 21fc84
-      TRACE_D3("  Compilation Unit @ offset 0x%lx:\n", cu_start_offset);
Jakub Jelinek 21fc84
-      /* parse_CU_header initialises the CU's set_abbv_Cursor cache
Jakub Jelinek 21fc84
-         (saC_cache) */
Jakub Jelinek 21fc84
-      parse_CU_Header( &cc, td3, &info,
Jakub Jelinek 21fc84
-                       (UChar*)debug_abbv_img, debug_abbv_sz );
Jakub Jelinek 21fc84
-      cc.debug_str_img    = debug_str_img;
Jakub Jelinek 21fc84
-      cc.debug_str_sz     = debug_str_sz;
Jakub Jelinek 21fc84
-      cc.debug_ranges_img = debug_ranges_img;
Jakub Jelinek 21fc84
-      cc.debug_ranges_sz  = debug_ranges_sz;
Jakub Jelinek 21fc84
-      cc.debug_loc_img    = debug_loc_img;
Jakub Jelinek 21fc84
-      cc.debug_loc_sz     = debug_loc_sz;
Jakub Jelinek 21fc84
-      cc.debug_line_img   = debug_line_img;
Jakub Jelinek 21fc84
-      cc.debug_line_sz    = debug_line_sz;
Jakub Jelinek 21fc84
-      cc.debug_info_img   = debug_info_img;
Jakub Jelinek 21fc84
-      cc.debug_info_sz    = debug_info_sz;
Jakub Jelinek 21fc84
-      cc.cu_start_offset  = cu_start_offset;
Jakub Jelinek 21fc84
-      cc.di = di;
Jakub Jelinek 21fc84
-      /* The CU's svma can be deduced by looking at the AT_low_pc
Jakub Jelinek 21fc84
-         value in the top level TAG_compile_unit, which is the topmost
Jakub Jelinek 21fc84
-         DIE.  We'll leave it for the 'varparser' to acquire that info
Jakub Jelinek 21fc84
-         and fill it in -- since it is the only party to want to know
Jakub Jelinek 21fc84
-         it. */
Jakub Jelinek 21fc84
-      cc.cu_svma_known = False;
Jakub Jelinek 21fc84
-      cc.cu_svma       = 0;
Jakub Jelinek 21fc84
-
Jakub Jelinek 21fc84
-      /* Create a fake outermost-level range covering the entire
Jakub Jelinek 21fc84
-         address range.  So we always have *something* to catch all
Jakub Jelinek 21fc84
-         variable declarations. */
Jakub Jelinek 21fc84
-      varstack_push( &cc, &varparser, td3, 
Jakub Jelinek 21fc84
-                     unitary_range_list(0UL, ~0UL),
Jakub Jelinek 21fc84
-                     -1, False/*isFunc*/, NULL/*fbGX*/ );
Jakub Jelinek 21fc84
-
Jakub Jelinek 21fc84
-      /* And set up the file name table.  When we come across the top
Jakub Jelinek 21fc84
-         level DIE for this CU (which is what the next call to
Jakub Jelinek 21fc84
-         read_DIE should process) we will copy all the file names out
Jakub Jelinek 21fc84
-         of the .debug_line img area and use this table to look up the
Jakub Jelinek 21fc84
-         copies when we later see filename numbers in DW_TAG_variables
Jakub Jelinek 21fc84
-         etc. */
Jakub Jelinek 21fc84
-      vg_assert(!varparser.filenameTable );
Jakub Jelinek 21fc84
-      varparser.filenameTable 
Jakub Jelinek 21fc84
-         = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.5",
Jakub Jelinek 21fc84
-                       ML_(dinfo_free),
Jakub Jelinek 21fc84
-                       sizeof(UChar*) );
Jakub Jelinek 21fc84
-      vg_assert(varparser.filenameTable);
Jakub Jelinek 21fc84
+   /* Perform two DIE-reading passes.  The first pass reads DIEs from
Jakub Jelinek 21fc84
+      .debug_info, and the second pass reads DIEs from .debug_types.
Jakub Jelinek 21fc84
+      Moving the body of this loop into a separate function would
Jakub Jelinek 21fc84
+      require a large number of arguments to be passed in, so it is
Jakub Jelinek 21fc84
+      kept inline instead.  */
Jakub Jelinek 21fc84
+   for (pass = 0; pass < 2; ++pass) {
Jakub Jelinek 21fc84
+      UWord section_size;
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+      if (pass == 0) {
Jakub Jelinek 21fc84
+         /* Now loop over the Compilation Units listed in the .debug_info
Jakub Jelinek 21fc84
+            section (see D3SPEC sec 7.5) paras 1 and 2.  Each compilation
Jakub Jelinek 21fc84
+            unit contains a Compilation Unit Header followed by precisely
Jakub Jelinek 21fc84
+            one DW_TAG_compile_unit or DW_TAG_partial_unit DIE. */
Jakub Jelinek 21fc84
+         init_Cursor( &info, debug_info_img, debug_info_sz, 0, barf,
Jakub Jelinek 21fc84
+                      "Overrun whilst reading .debug_info section" );
Jakub Jelinek 21fc84
+         section_size = debug_info_sz;
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
-      /* Now read the one-and-only top-level DIE for this CU. */
Jakub Jelinek 21fc84
-      vg_assert(varparser.sp == 0);
Jakub Jelinek 21fc84
-      read_DIE( rangestree,
Jakub Jelinek 21fc84
-                tyents, tempvars, gexprs,
Jakub Jelinek 21fc84
-                &typarser, &varparser,
Jakub Jelinek 21fc84
-                &info, td3, &cc, 0 );
Jakub Jelinek 21fc84
-
Jakub Jelinek 21fc84
-      cu_offset_now = get_position_of_Cursor( &info );
Jakub Jelinek 21fc84
-
Jakub Jelinek 21fc84
-      if (0) VG_(printf)("Travelled: %lu  size %llu\n",
Jakub Jelinek 21fc84
-                         cu_offset_now - cc.cu_start_offset,
Jakub Jelinek 21fc84
-                         cc.unit_length + (cc.is_dw64 ? 12 : 4));
Jakub Jelinek 21fc84
-
Jakub Jelinek 21fc84
-      /* How big the CU claims it is .. */
Jakub Jelinek 21fc84
-      cu_size_including_IniLen = cc.unit_length + (cc.is_dw64 ? 12 : 4);
Jakub Jelinek 21fc84
-      /* .. vs how big we have found it to be */
Jakub Jelinek 21fc84
-      cu_amount_used = cu_offset_now - cc.cu_start_offset;
Jakub Jelinek 21fc84
-
Jakub Jelinek 21fc84
-      if (1) TRACE_D3("offset now %ld, d-i-size %ld\n",
Jakub Jelinek 21fc84
-                      cu_offset_now, debug_info_sz);
Jakub Jelinek 21fc84
-      if (cu_offset_now > debug_info_sz)
Jakub Jelinek 21fc84
-         barf("toplevel DIEs beyond end of CU");
Jakub Jelinek 21fc84
-
Jakub Jelinek 21fc84
-      /* If the CU is bigger than it claims to be, we've got a serious
Jakub Jelinek 21fc84
-         problem. */
Jakub Jelinek 21fc84
-      if (cu_amount_used > cu_size_including_IniLen)
Jakub Jelinek 21fc84
-         barf("CU's actual size appears to be larger than it claims it is");
Jakub Jelinek 21fc84
-
Jakub Jelinek 21fc84
-      /* If the CU is smaller than it claims to be, we need to skip some
Jakub Jelinek 21fc84
-         bytes.  Loop updates cu_offset_new and cu_amount_used. */
Jakub Jelinek 21fc84
-      while (cu_amount_used < cu_size_including_IniLen
Jakub Jelinek 21fc84
-             && get_remaining_length_Cursor( &info ) > 0) {
Jakub Jelinek 21fc84
-         if (0) VG_(printf)("SKIP\n");
Jakub Jelinek 21fc84
-         (void)get_UChar( &info );
Jakub Jelinek 21fc84
-         cu_offset_now = get_position_of_Cursor( &info );
Jakub Jelinek 21fc84
-         cu_amount_used = cu_offset_now - cc.cu_start_offset;
Jakub Jelinek 21fc84
+         TRACE_D3("\n------ Parsing .debug_info section ------\n");
Jakub Jelinek 21fc84
+      } else {
Jakub Jelinek 21fc84
+         if (debug_types_img == NULL)
Jakub Jelinek 21fc84
+            continue;
Jakub Jelinek 21fc84
+         init_Cursor( &info, debug_types_img, debug_types_sz, 0, barf,
Jakub Jelinek 21fc84
+                      "Overrun whilst reading .debug_types section" );
Jakub Jelinek 21fc84
+         section_size = debug_types_sz;
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         TRACE_D3("\n------ Parsing .debug_types section ------\n");
Jakub Jelinek 21fc84
       }
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
-      /* Preen to level -2.  DIEs have level >= 0 so -2 cannot occur
Jakub Jelinek 21fc84
-         anywhere else at all.  Our fake the-entire-address-space
Jakub Jelinek 21fc84
-         range is at level -1, so preening to -2 should completely
Jakub Jelinek 21fc84
-         empty the stack out. */
Jakub Jelinek 21fc84
-      TRACE_D3("\n");
Jakub Jelinek 21fc84
-      varstack_preen( &varparser, td3, -2 );
Jakub Jelinek 21fc84
-      /* Similarly, empty the type stack out. */
Jakub Jelinek 21fc84
-      typestack_preen( &typarser, td3, -2 );
Jakub Jelinek 21fc84
+      while (True) {
Jakub Jelinek 21fc84
+         UWord   cu_start_offset, cu_offset_now;
Jakub Jelinek 21fc84
+         CUConst cc;
Jakub Jelinek 21fc84
+         /* It may be that the stated size of this CU is larger than the
Jakub Jelinek 21fc84
+            amount of stuff actually in it.  icc9 seems to generate CUs
Jakub Jelinek 21fc84
+            thusly.  We use these variables to figure out if this is
Jakub Jelinek 21fc84
+            indeed the case, and if so how many bytes we need to skip to
Jakub Jelinek 21fc84
+            get to the start of the next CU.  Not skipping those bytes
Jakub Jelinek 21fc84
+            causes us to misidentify the start of the next CU, and it all
Jakub Jelinek 21fc84
+            goes badly wrong after that (not surprisingly). */
Jakub Jelinek 21fc84
+         UWord cu_size_including_IniLen, cu_amount_used;
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         /* It seems icc9 finishes the DIE info before debug_info_sz
Jakub Jelinek 21fc84
+            bytes have been used up.  So be flexible, and declare the
Jakub Jelinek 21fc84
+            sequence complete if there is not enough remaining bytes to
Jakub Jelinek 21fc84
+            hold even the smallest conceivable CU header.  (11 bytes I
Jakub Jelinek 21fc84
+            reckon). */
Jakub Jelinek 21fc84
+         /* JRS 23Jan09: I suspect this is no longer necessary now that
Jakub Jelinek 21fc84
+            the code below contains a 'while (cu_amount_used <
Jakub Jelinek 21fc84
+            cu_size_including_IniLen ...'  style loop, which skips over
Jakub Jelinek 21fc84
+            any leftover bytes at the end of a CU in the case where the
Jakub Jelinek 21fc84
+            CU's stated size is larger than its actual size (as
Jakub Jelinek 21fc84
+            determined by reading all its DIEs).  However, for prudence,
Jakub Jelinek 21fc84
+            I'll leave the following test in place.  I can't see that a
Jakub Jelinek 21fc84
+            CU header can be smaller than 11 bytes, so I don't think
Jakub Jelinek 21fc84
+            there's any harm possible through the test -- it just adds
Jakub Jelinek 21fc84
+            robustness. */
Jakub Jelinek 21fc84
+         Word avail = get_remaining_length_Cursor( &info );
Jakub Jelinek 21fc84
+         if (avail < 11) {
Jakub Jelinek 21fc84
+            if (avail > 0)
Jakub Jelinek 21fc84
+               TRACE_D3("new_dwarf3_reader_wrk: warning: "
Jakub Jelinek 21fc84
+                        "%ld unused bytes after end of DIEs\n", avail);
Jakub Jelinek 21fc84
+            break;
Jakub Jelinek 21fc84
+         }
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         /* Check the varparser's stack is in a sane state. */
Jakub Jelinek 21fc84
+         vg_assert(varparser.sp == -1);
Jakub Jelinek 21fc84
+         for (i = 0; i < N_D3_VAR_STACK; i++) {
Jakub Jelinek 21fc84
+            vg_assert(varparser.ranges[i] == NULL);
Jakub Jelinek 21fc84
+            vg_assert(varparser.level[i] == 0);
Jakub Jelinek 21fc84
+         }
Jakub Jelinek 21fc84
+         for (i = 0; i < N_D3_TYPE_STACK; i++) {
Jakub Jelinek 21fc84
+            vg_assert(typarser.qparentE[i].cuOff == D3_INVALID_CUOFF);
Jakub Jelinek 21fc84
+            vg_assert(typarser.qparentE[i].tag   == Te_EMPTY);
Jakub Jelinek 21fc84
+            vg_assert(typarser.qlevel[i] == 0);
Jakub Jelinek 21fc84
+         }
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         cu_start_offset = get_position_of_Cursor( &info );
Jakub Jelinek 21fc84
+         TRACE_D3("\n");
Jakub Jelinek 21fc84
+         TRACE_D3("  Compilation Unit @ offset 0x%lx:\n", cu_start_offset);
Jakub Jelinek 21fc84
+         /* parse_CU_header initialises the CU's set_abbv_Cursor cache
Jakub Jelinek 21fc84
+            (saC_cache) */
Jakub Jelinek 21fc84
+         parse_CU_Header( &cc, td3, &info,
Jakub Jelinek 21fc84
+                          (UChar*)debug_abbv_img, debug_abbv_sz,
Jakub Jelinek 21fc84
+                          pass != 0 );
Jakub Jelinek 21fc84
+         cc.debug_str_img    = debug_str_img;
Jakub Jelinek 21fc84
+         cc.debug_str_sz     = debug_str_sz;
Jakub Jelinek 21fc84
+         cc.debug_ranges_img = debug_ranges_img;
Jakub Jelinek 21fc84
+         cc.debug_ranges_sz  = debug_ranges_sz;
Jakub Jelinek 21fc84
+         cc.debug_loc_img    = debug_loc_img;
Jakub Jelinek 21fc84
+         cc.debug_loc_sz     = debug_loc_sz;
Jakub Jelinek 21fc84
+         cc.debug_line_img   = debug_line_img;
Jakub Jelinek 21fc84
+         cc.debug_line_sz    = debug_line_sz;
Jakub Jelinek 21fc84
+         cc.debug_info_img   = debug_info_img;
Jakub Jelinek 21fc84
+         cc.debug_info_sz    = debug_info_sz;
Jakub Jelinek 21fc84
+         cc.debug_types_img  = debug_types_img;
Jakub Jelinek 21fc84
+         cc.debug_types_sz   = debug_types_sz;
Jakub Jelinek 21fc84
+         cc.cu_start_offset  = cu_start_offset;
Jakub Jelinek 21fc84
+         cc.di = di;
Jakub Jelinek 21fc84
+         /* The CU's svma can be deduced by looking at the AT_low_pc
Jakub Jelinek 21fc84
+            value in the top level TAG_compile_unit, which is the topmost
Jakub Jelinek 21fc84
+            DIE.  We'll leave it for the 'varparser' to acquire that info
Jakub Jelinek 21fc84
+            and fill it in -- since it is the only party to want to know
Jakub Jelinek 21fc84
+            it. */
Jakub Jelinek 21fc84
+         cc.cu_svma_known = False;
Jakub Jelinek 21fc84
+         cc.cu_svma       = 0;
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         cc.signature_types = signature_types;
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         /* Create a fake outermost-level range covering the entire
Jakub Jelinek 21fc84
+            address range.  So we always have *something* to catch all
Jakub Jelinek 21fc84
+            variable declarations. */
Jakub Jelinek 21fc84
+         varstack_push( &cc, &varparser, td3, 
Jakub Jelinek 21fc84
+                        unitary_range_list(0UL, ~0UL),
Jakub Jelinek 21fc84
+                        -1, False/*isFunc*/, NULL/*fbGX*/ );
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         /* And set up the file name table.  When we come across the top
Jakub Jelinek 21fc84
+            level DIE for this CU (which is what the next call to
Jakub Jelinek 21fc84
+            read_DIE should process) we will copy all the file names out
Jakub Jelinek 21fc84
+            of the .debug_line img area and use this table to look up the
Jakub Jelinek 21fc84
+            copies when we later see filename numbers in DW_TAG_variables
Jakub Jelinek 21fc84
+            etc. */
Jakub Jelinek 21fc84
+         vg_assert(!varparser.filenameTable );
Jakub Jelinek 21fc84
+         varparser.filenameTable 
Jakub Jelinek 21fc84
+            = VG_(newXA)( ML_(dinfo_zalloc), "di.readdwarf3.ndrw.5",
Jakub Jelinek 21fc84
+                          ML_(dinfo_free),
Jakub Jelinek 21fc84
+                          sizeof(UChar*) );
Jakub Jelinek 21fc84
+         vg_assert(varparser.filenameTable);
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         /* Now read the one-and-only top-level DIE for this CU. */
Jakub Jelinek 21fc84
+         vg_assert(varparser.sp == 0);
Jakub Jelinek 21fc84
+         read_DIE( rangestree,
Jakub Jelinek 21fc84
+                   tyents, tempvars, gexprs,
Jakub Jelinek 21fc84
+                   &typarser, &varparser,
Jakub Jelinek 21fc84
+                   &info, td3, &cc, 0 );
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
-      if (cu_offset_now == debug_info_sz)
Jakub Jelinek 21fc84
-         break;
Jakub Jelinek 21fc84
-      /* else keep going */
Jakub Jelinek 21fc84
+         cu_offset_now = get_position_of_Cursor( &info );
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
-      TRACE_D3("set_abbv_Cursor cache: %lu queries, %lu misses\n",
Jakub Jelinek 21fc84
-               cc.saC_cache_queries, cc.saC_cache_misses);
Jakub Jelinek 21fc84
+         if (0) VG_(printf)("Travelled: %lu  size %llu\n",
Jakub Jelinek 21fc84
+                            cu_offset_now - cc.cu_start_offset,
Jakub Jelinek 21fc84
+                            cc.unit_length + (cc.is_dw64 ? 12 : 4));
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         /* How big the CU claims it is .. */
Jakub Jelinek 21fc84
+         cu_size_including_IniLen = cc.unit_length + (cc.is_dw64 ? 12 : 4);
Jakub Jelinek 21fc84
+         /* .. vs how big we have found it to be */
Jakub Jelinek 21fc84
+         cu_amount_used = cu_offset_now - cc.cu_start_offset;
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
-      vg_assert(varparser.filenameTable );
Jakub Jelinek 21fc84
-      VG_(deleteXA)( varparser.filenameTable );
Jakub Jelinek 21fc84
-      varparser.filenameTable = NULL;
Jakub Jelinek 21fc84
+         if (1) TRACE_D3("offset now %ld, d-i-size %ld\n",
Jakub Jelinek 21fc84
+                         cu_offset_now, section_size);
Jakub Jelinek 21fc84
+         if (cu_offset_now > section_size)
Jakub Jelinek 21fc84
+            barf("toplevel DIEs beyond end of CU");
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         /* If the CU is bigger than it claims to be, we've got a serious
Jakub Jelinek 21fc84
+            problem. */
Jakub Jelinek 21fc84
+         if (cu_amount_used > cu_size_including_IniLen)
Jakub Jelinek 21fc84
+            barf("CU's actual size appears to be larger than it claims it is");
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         /* If the CU is smaller than it claims to be, we need to skip some
Jakub Jelinek 21fc84
+            bytes.  Loop updates cu_offset_new and cu_amount_used. */
Jakub Jelinek 21fc84
+         while (cu_amount_used < cu_size_including_IniLen
Jakub Jelinek 21fc84
+                && get_remaining_length_Cursor( &info ) > 0) {
Jakub Jelinek 21fc84
+            if (0) VG_(printf)("SKIP\n");
Jakub Jelinek 21fc84
+            (void)get_UChar( &info );
Jakub Jelinek 21fc84
+            cu_offset_now = get_position_of_Cursor( &info );
Jakub Jelinek 21fc84
+            cu_amount_used = cu_offset_now - cc.cu_start_offset;
Jakub Jelinek 21fc84
+         }
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         /* Preen to level -2.  DIEs have level >= 0 so -2 cannot occur
Jakub Jelinek 21fc84
+            anywhere else at all.  Our fake the-entire-address-space
Jakub Jelinek 21fc84
+            range is at level -1, so preening to -2 should completely
Jakub Jelinek 21fc84
+            empty the stack out. */
Jakub Jelinek 21fc84
+         TRACE_D3("\n");
Jakub Jelinek 21fc84
+         varstack_preen( &varparser, td3, -2 );
Jakub Jelinek 21fc84
+         /* Similarly, empty the type stack out. */
Jakub Jelinek 21fc84
+         typestack_preen( &typarser, td3, -2 );
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         TRACE_D3("set_abbv_Cursor cache: %lu queries, %lu misses\n",
Jakub Jelinek 21fc84
+                  cc.saC_cache_queries, cc.saC_cache_misses);
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         vg_assert(varparser.filenameTable );
Jakub Jelinek 21fc84
+         VG_(deleteXA)( varparser.filenameTable );
Jakub Jelinek 21fc84
+         varparser.filenameTable = NULL;
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+         if (cu_offset_now == section_size)
Jakub Jelinek 21fc84
+            break;
Jakub Jelinek 21fc84
+         /* else keep going */
Jakub Jelinek 21fc84
+      }
Jakub Jelinek 21fc84
    }
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
    /* From here on we're post-processing the stuff we got
Jakub Jelinek 21fc84
@@ -3973,14 +4183,10 @@ void new_dwarf3_reader_wrk (
Jakub Jelinek 21fc84
    ML_(dinfo_free)( tyents_to_keep_cache );
Jakub Jelinek 21fc84
    tyents_to_keep_cache = NULL;
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
-   /* and the file name table (just the array, not the entries
Jakub Jelinek 21fc84
-      themselves).  (Apparently, 2008-Oct-23, varparser.filenameTable
Jakub Jelinek 21fc84
-      can be NULL here, for icc9 generated Dwarf3.  Not sure what that
Jakub Jelinek 21fc84
-      signifies (a deeper problem with the reader?)) */
Jakub Jelinek 21fc84
-   if (varparser.filenameTable) {
Jakub Jelinek 21fc84
-      VG_(deleteXA)( varparser.filenameTable );
Jakub Jelinek 21fc84
-      varparser.filenameTable = NULL;
Jakub Jelinek 21fc84
-   }
Jakub Jelinek 21fc84
+   vg_assert( varparser.filenameTable == NULL );
Jakub Jelinek 21fc84
+
Jakub Jelinek 21fc84
+   /* And the signatured type hash.  */
Jakub Jelinek 21fc84
+   VG_(HT_destruct) ( signature_types, ML_(dinfo_free) );
Jakub Jelinek 21fc84
 
Jakub Jelinek 21fc84
    /* record the GExprs in di so they can be freed later */
Jakub Jelinek 21fc84
    vg_assert(!di->admin_gexprs);
Jakub Jelinek 21fc84
@@ -4011,6 +4217,7 @@ void
Jakub Jelinek 21fc84
 ML_(new_dwarf3_reader) (
Jakub Jelinek 21fc84
    struct _DebugInfo* di,
Jakub Jelinek 21fc84
    UChar* debug_info_img,   SizeT debug_info_sz,
Jakub Jelinek 21fc84
+   UChar* debug_types_img,  SizeT debug_types_sz,
Jakub Jelinek 21fc84
    UChar* debug_abbv_img,   SizeT debug_abbv_sz,
Jakub Jelinek 21fc84
    UChar* debug_line_img,   SizeT debug_line_sz,
Jakub Jelinek 21fc84
    UChar* debug_str_img,    SizeT debug_str_sz,
Jakub Jelinek 21fc84
@@ -4034,6 +4241,7 @@ ML_(new_dwarf3_reader) (
Jakub Jelinek 21fc84
       /* try this ... */
Jakub Jelinek 21fc84
       new_dwarf3_reader_wrk( di, barf,
Jakub Jelinek 21fc84
                              debug_info_img,   debug_info_sz,
Jakub Jelinek 21fc84
+                             debug_types_img,  debug_types_sz,
Jakub Jelinek 21fc84
                              debug_abbv_img,   debug_abbv_sz,
Jakub Jelinek 21fc84
                              debug_line_img,   debug_line_sz,
Jakub Jelinek 21fc84
                              debug_str_img,    debug_str_sz,
Jakub Jelinek 21fc84
--- valgrind-3.7.0/coregrind/m_debuginfo/readmacho.c	(revision 12490)
Jakub Jelinek 21fc84
+++ valgrind-3.7.0/coregrind/m_debuginfo/readmacho.c	(revision 12491)
Jakub Jelinek 21fc84
@@ -1068,6 +1068,7 @@ Bool ML_(read_macho_debug_info)( struct
Jakub Jelinek 21fc84
          /* The old reader: line numbers and unwind info only */
Jakub Jelinek 21fc84
          ML_(read_debuginfo_dwarf3) ( di,
Jakub Jelinek 21fc84
                                       debug_info_img, debug_info_sz,
Jakub Jelinek 21fc84
+				      NULL,           0,
Jakub Jelinek 21fc84
                                       debug_abbv_img, debug_abbv_sz,
Jakub Jelinek 21fc84
                                       debug_line_img, debug_line_sz,
Jakub Jelinek 21fc84
                                       debug_str_img,  debug_str_sz );
Jakub Jelinek 21fc84
@@ -1080,6 +1081,7 @@ Bool ML_(read_macho_debug_info)( struct
Jakub Jelinek 21fc84
              || VG_(clo_read_var_info) /* the user asked for it */) {
Jakub Jelinek 21fc84
             ML_(new_dwarf3_reader)(
Jakub Jelinek 21fc84
                di, debug_info_img,   debug_info_sz,
Jakub Jelinek 21fc84
+	           NULL,             0,
Jakub Jelinek 21fc84
                    debug_abbv_img,   debug_abbv_sz,
Jakub Jelinek 21fc84
                    debug_line_img,   debug_line_sz,
Jakub Jelinek 21fc84
                    debug_str_img,    debug_str_sz,
Jakub Jelinek 21fc84
--- valgrind-3.7.0/coregrind/m_debuginfo/priv_readdwarf3.h	(revision 12490)
Jakub Jelinek 21fc84
+++ valgrind-3.7.0/coregrind/m_debuginfo/priv_readdwarf3.h	(revision 12491)
Jakub Jelinek 21fc84
@@ -43,6 +43,7 @@ void
Jakub Jelinek 21fc84
 ML_(new_dwarf3_reader) (
Jakub Jelinek 21fc84
    struct _DebugInfo* di,
Jakub Jelinek 21fc84
    UChar* debug_info_img,   SizeT debug_info_sz,
Jakub Jelinek 21fc84
+   UChar* debug_types_img,  SizeT debug_types_sz,
Jakub Jelinek 21fc84
    UChar* debug_abbv_img,   SizeT debug_abbv_sz,
Jakub Jelinek 21fc84
    UChar* debug_line_img,   SizeT debug_line_sz,
Jakub Jelinek 21fc84
    UChar* debug_str_img,    SizeT debug_str_sz,