Jakub Jelinek 0332e1
--- valgrind/coregrind/m_debuginfo/readdwarf.c.jj	2010-04-07 11:10:52.000000000 +0200
Jakub Jelinek 0332e1
+++ valgrind/coregrind/m_debuginfo/readdwarf.c	2010-04-07 12:34:56.000000000 +0200
Jakub Jelinek 0332e1
@@ -1,6 +1,6 @@
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
 /*--------------------------------------------------------------------*/
Jakub Jelinek 0332e1
-/*--- Read DWARF1/2/3 debug info.                      readdwarf.c ---*/
Jakub Jelinek 0332e1
+/*--- Read DWARF1/2/3/4 debug info.                    readdwarf.c ---*/
Jakub Jelinek 0332e1
 /*--------------------------------------------------------------------*/
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
 /*
Jakub Jelinek 0332e1
@@ -139,6 +139,7 @@ typedef struct
Jakub Jelinek 0332e1
   UShort li_version;
Jakub Jelinek 0332e1
   ULong  li_header_length;
Jakub Jelinek 0332e1
   UChar  li_min_insn_length;
Jakub Jelinek 0332e1
+  UChar  li_max_ops_per_insn;
Jakub Jelinek 0332e1
   UChar  li_default_is_stmt;
Jakub Jelinek 0332e1
   Int    li_line_base;
Jakub Jelinek 0332e1
   UChar  li_line_range;
Jakub Jelinek 0332e1
@@ -182,7 +183,8 @@ enum dwarf_line_number_x_ops
Jakub Jelinek 0332e1
   {
Jakub Jelinek 0332e1
     DW_LNE_end_sequence = 1,
Jakub Jelinek 0332e1
     DW_LNE_set_address = 2,
Jakub Jelinek 0332e1
-    DW_LNE_define_file = 3
Jakub Jelinek 0332e1
+    DW_LNE_define_file = 3,
Jakub Jelinek 0332e1
+    DW_LNE_set_discriminator = 4
Jakub Jelinek 0332e1
   };
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
 typedef struct
Jakub Jelinek 0332e1
@@ -199,7 +201,8 @@ typedef struct
Jakub Jelinek 0332e1
   UInt  column;
Jakub Jelinek 0332e1
   Int   is_stmt;
Jakub Jelinek 0332e1
   Int   basic_block;
Jakub Jelinek 0332e1
-  Int   end_sequence;
Jakub Jelinek 0332e1
+  UChar end_sequence;
Jakub Jelinek 0332e1
+  UChar op_index;
Jakub Jelinek 0332e1
 } LineSMR;
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
@@ -302,6 +305,7 @@ void reset_state_machine ( Int is_stmt )
Jakub Jelinek 0332e1
    state_machine_regs.is_stmt = is_stmt;
Jakub Jelinek 0332e1
    state_machine_regs.basic_block = 0;
Jakub Jelinek 0332e1
    state_machine_regs.end_sequence = 0;
Jakub Jelinek 0332e1
+   state_machine_regs.op_index = 0;
Jakub Jelinek 0332e1
 }
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
 /* Look up a directory name, or return NULL if unknown. */
Jakub Jelinek 0332e1
@@ -393,6 +397,7 @@ Word process_extended_line_op( struct _D
Jakub Jelinek 0332e1
       case DW_LNE_set_address:
Jakub Jelinek 0332e1
          adr = *((Addr *)data);
Jakub Jelinek 0332e1
          state_machine_regs.address = adr;
Jakub Jelinek 0332e1
+         state_machine_regs.op_index = 0;
Jakub Jelinek 0332e1
          if (di->ddump_line)
Jakub Jelinek 0332e1
             VG_(printf)("  Extended opcode %d: set Address to 0x%lx\n",
Jakub Jelinek 0332e1
                         (Int)op_code, (Addr)adr);
Jakub Jelinek 0332e1
@@ -411,6 +416,11 @@ Word process_extended_line_op( struct _D
Jakub Jelinek 0332e1
             VG_(printf)("  DWARF2-line: set_address\n");
Jakub Jelinek 0332e1
          break;
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
+      case DW_LNE_set_discriminator:
Jakub Jelinek 0332e1
+         read_leb128 (data, & bytes_read, 0);
Jakub Jelinek 0332e1
+         data += bytes_read;
Jakub Jelinek 0332e1
+         break;
Jakub Jelinek 0332e1
+
Jakub Jelinek 0332e1
       default:
Jakub Jelinek 0332e1
          if (di->ddump_line)
Jakub Jelinek 0332e1
             VG_(printf)("process_extended_line_op:default\n");
Jakub Jelinek 0332e1
@@ -513,9 +523,9 @@ void read_dwarf2_lineblock ( struct _Deb
Jakub Jelinek 0332e1
       VG_(printf)("  DWARF Version:               %d\n", 
Jakub Jelinek 0332e1
                   (Int)info.li_version);
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
-   if (info.li_version != 2 && info.li_version != 3) {
Jakub Jelinek 0332e1
+   if (info.li_version != 2 && info.li_version != 3 && info.li_version != 4) {
Jakub Jelinek 0332e1
       ML_(symerr)(di, True,
Jakub Jelinek 0332e1
-                  "Only DWARF version 2 and 3 line info "
Jakub Jelinek 0332e1
+                  "Only DWARF version 2, 3 and 4 line info "
Jakub Jelinek 0332e1
                   "is currently supported.");
Jakub Jelinek 0332e1
       goto out;
Jakub Jelinek 0332e1
    }
Jakub Jelinek 0332e1
@@ -533,6 +543,20 @@ void read_dwarf2_lineblock ( struct _Deb
Jakub Jelinek 0332e1
       VG_(printf)("  Minimum Instruction Length:  %d\n", 
Jakub Jelinek 0332e1
                   (Int)info.li_min_insn_length);
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
+   if (info.li_version >= 4) {
Jakub Jelinek 0332e1
+      info.li_max_ops_per_insn = * ((UChar *)external);
Jakub Jelinek 0332e1
+      if (info.li_max_ops_per_insn == 0) {
Jakub Jelinek 0332e1
+         ML_(symerr)(di, True,
Jakub Jelinek 0332e1
+                     "Invalid Maximum Ops Per Insn in line info.");
Jakub Jelinek 0332e1
+         goto out;
Jakub Jelinek 0332e1
+      }
Jakub Jelinek 0332e1
+      external += 1;
Jakub Jelinek 0332e1
+      if (di->ddump_line)
Jakub Jelinek 0332e1
+         VG_(printf)("  Maximum Ops Per Insn:        %d\n", 
Jakub Jelinek 0332e1
+                  (Int)info.li_max_ops_per_insn);
Jakub Jelinek 0332e1
+   } else
Jakub Jelinek 0332e1
+      info.li_max_ops_per_insn = 1;
Jakub Jelinek 0332e1
+
Jakub Jelinek 0332e1
    info.li_default_is_stmt = * ((UChar *)external);
Jakub Jelinek 0332e1
    external += 1;
Jakub Jelinek 0332e1
    if (di->ddump_line)
Jakub Jelinek 0332e1
@@ -714,10 +738,18 @@ void read_dwarf2_lineblock ( struct _Deb
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
          Int advAddr;
Jakub Jelinek 0332e1
          op_code -= info.li_opcode_base;
Jakub Jelinek 0332e1
-         adv      = (op_code / info.li_line_range) 
Jakub Jelinek 0332e1
-                       * info.li_min_insn_length;
Jakub Jelinek 0332e1
-         advAddr = adv;
Jakub Jelinek 0332e1
-         state_machine_regs.address += adv;
Jakub Jelinek 0332e1
+         adv      = (op_code / info.li_line_range);
Jakub Jelinek 0332e1
+         if (info.li_max_ops_per_insn == 1) {
Jakub Jelinek 0332e1
+            adv *= info.li_min_insn_length;
Jakub Jelinek 0332e1
+            advAddr = adv;
Jakub Jelinek 0332e1
+            state_machine_regs.address += adv;
Jakub Jelinek 0332e1
+         } else {
Jakub Jelinek 0332e1
+            advAddr = ((state_machine_regs.op_index + adv)
Jakub Jelinek 0332e1
+                       / info.li_max_ops_per_insn) * info.li_min_insn_length;
Jakub Jelinek 0332e1
+            state_machine_regs.address += advAddr;
Jakub Jelinek 0332e1
+            state_machine_regs.op_index = (state_machine_regs.op_index + adv)
Jakub Jelinek 0332e1
+                                          % info.li_max_ops_per_insn;
Jakub Jelinek 0332e1
+         }
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
          if (0) VG_(printf)("smr.a += %#x\n", adv );
Jakub Jelinek 0332e1
          adv = (op_code % info.li_line_range) + info.li_line_base;
Jakub Jelinek 0332e1
@@ -800,10 +832,19 @@ void read_dwarf2_lineblock ( struct _Deb
Jakub Jelinek 0332e1
             break;
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
          case DW_LNS_advance_pc:
Jakub Jelinek 0332e1
-            adv = info.li_min_insn_length 
Jakub Jelinek 0332e1
-                     * read_leb128 (data, & bytes_read, 0);
Jakub Jelinek 0332e1
+            adv = read_leb128 (data, & bytes_read, 0);
Jakub Jelinek 0332e1
             data += bytes_read;
Jakub Jelinek 0332e1
-            state_machine_regs.address += adv;
Jakub Jelinek 0332e1
+            if (info.li_max_ops_per_insn == 1) {
Jakub Jelinek 0332e1
+               adv *= info.li_min_insn_length;
Jakub Jelinek 0332e1
+               state_machine_regs.address += adv;
Jakub Jelinek 0332e1
+            } else {
Jakub Jelinek 0332e1
+               state_machine_regs.address
Jakub Jelinek 0332e1
+                 += ((state_machine_regs.op_index + adv)
Jakub Jelinek 0332e1
+                     / info.li_max_ops_per_insn) * info.li_min_insn_length;
Jakub Jelinek 0332e1
+               state_machine_regs.op_index
Jakub Jelinek 0332e1
+                 = (state_machine_regs.op_index + adv)
Jakub Jelinek 0332e1
+                   % info.li_max_ops_per_insn;
Jakub Jelinek 0332e1
+            }
Jakub Jelinek 0332e1
             if (0) VG_(printf)("smr.a += %#x\n", adv );
Jakub Jelinek 0332e1
             if (di->ddump_line)
Jakub Jelinek 0332e1
                VG_(printf)("  Advance PC by %d to 0x%lx\n", 
Jakub Jelinek 0332e1
@@ -851,9 +892,18 @@ void read_dwarf2_lineblock ( struct _Deb
Jakub Jelinek 0332e1
             break;
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
          case DW_LNS_const_add_pc:
Jakub Jelinek 0332e1
-            adv = (((255 - info.li_opcode_base) / info.li_line_range)
Jakub Jelinek 0332e1
-                   * info.li_min_insn_length);
Jakub Jelinek 0332e1
-            state_machine_regs.address += adv;
Jakub Jelinek 0332e1
+            adv = ((255 - info.li_opcode_base) / info.li_line_range);
Jakub Jelinek 0332e1
+            if (info.li_max_ops_per_insn == 1) {
Jakub Jelinek 0332e1
+               adv *= info.li_min_insn_length;
Jakub Jelinek 0332e1
+               state_machine_regs.address += adv;
Jakub Jelinek 0332e1
+            } else {
Jakub Jelinek 0332e1
+               state_machine_regs.address
Jakub Jelinek 0332e1
+                 += ((state_machine_regs.op_index + adv)
Jakub Jelinek 0332e1
+                     / info.li_max_ops_per_insn) * info.li_min_insn_length;
Jakub Jelinek 0332e1
+               state_machine_regs.op_index
Jakub Jelinek 0332e1
+                 = (state_machine_regs.op_index + adv)
Jakub Jelinek 0332e1
+                   % info.li_max_ops_per_insn;
Jakub Jelinek 0332e1
+            }
Jakub Jelinek 0332e1
             if (0) VG_(printf)("smr.a += %#x\n", adv );
Jakub Jelinek 0332e1
             if (di->ddump_line)
Jakub Jelinek 0332e1
                VG_(printf)("  Advance PC by constant %d to 0x%lx\n", 
Jakub Jelinek 0332e1
@@ -865,6 +915,7 @@ void read_dwarf2_lineblock ( struct _Deb
Jakub Jelinek 0332e1
             adv = *((UShort *)data);
Jakub Jelinek 0332e1
             data += 2;
Jakub Jelinek 0332e1
             state_machine_regs.address += adv;
Jakub Jelinek 0332e1
+            state_machine_regs.op_index = 0;
Jakub Jelinek 0332e1
             if (0) VG_(printf)("smr.a += %#x\n", adv );
Jakub Jelinek 0332e1
             if (di->ddump_line)
Jakub Jelinek 0332e1
                VG_(printf)("  DWARF2-line: fixed_advance_pc\n");
Jakub Jelinek 0332e1
@@ -979,7 +1030,7 @@ void read_unitinfo_dwarf2( /*OUT*/UnitIn
Jakub Jelinek 0332e1
    blklen = read_initial_length_field( p, &ui->dw64 );
Jakub Jelinek 0332e1
    p += ui->dw64 ? 12 : 4;
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
-   /* version should be 2 */
Jakub Jelinek 0332e1
+   /* version should be 2, 3 or 4 */
Jakub Jelinek 0332e1
    ver = *((UShort*)p);
Jakub Jelinek 0332e1
    p += 2;
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
@@ -1066,7 +1117,11 @@ void read_unitinfo_dwarf2( /*OUT*/UnitIn
Jakub Jelinek 0332e1
             case 0x08: /* FORM_string */    sval = (Char*)p; 
Jakub Jelinek 0332e1
                                             p += VG_(strlen)((Char*)p) + 1; break;
Jakub Jelinek 0332e1
             case 0x0b: /* FORM_data1 */     cval = *p; p++; break;
Jakub Jelinek 0332e1
-            
Jakub Jelinek 0332e1
+            case 0x17: /* FORM_sec_offset */if (ui->dw64) {
Jakub Jelinek 0332e1
+                                               cval = *((ULong*)p); p += 8; break;
Jakub Jelinek 0332e1
+                                            }
Jakub Jelinek 0332e1
+                                            cval = *((UInt*)p); p += 4; break;
Jakub Jelinek 0332e1
+
Jakub Jelinek 0332e1
             /* TODO : Following ones just skip data - implement if you need */
Jakub Jelinek 0332e1
             case 0x01: /* FORM_addr */      p += addr_size; break;
Jakub Jelinek 0332e1
             case 0x03: /* FORM_block2 */    p += *((UShort*)p) + 2; break;
Jakub Jelinek 0332e1
@@ -1085,7 +1140,10 @@ void read_unitinfo_dwarf2( /*OUT*/UnitIn
Jakub Jelinek 0332e1
             case 0x13: /* FORM_ref4 */      p += 4; break;
Jakub Jelinek 0332e1
             case 0x14: /* FORM_ref8 */      p += 8; break;
Jakub Jelinek 0332e1
             case 0x15: /* FORM_ref_udata */ read_leb128U( &p ); break;
Jakub Jelinek 0332e1
-            
Jakub Jelinek 0332e1
+            case 0x18: /* FORM_exprloc */   p += read_leb128U( &p ); break;
Jakub Jelinek 0332e1
+            case 0x19: /* FORM_flag_present */break;
Jakub Jelinek 0332e1
+            case 0x20: /* FORM_ref_sig8 */  p += 8; break;
Jakub Jelinek 0332e1
+
Jakub Jelinek 0332e1
             default:
Jakub Jelinek 0332e1
                VG_(printf)( "### unhandled dwarf2 abbrev form code 0x%x\n", form );
Jakub Jelinek 0332e1
                break;
Jakub Jelinek 0332e1
@@ -1163,9 +1221,9 @@ void ML_(read_debuginfo_dwarf3)
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
       /* version should be 2 */
Jakub Jelinek 0332e1
       ver = *((UShort*)( block_img + blklen_len ));
Jakub Jelinek 0332e1
-      if ( ver != 2 && ver != 3 ) {
Jakub Jelinek 0332e1
+      if ( ver != 2 && ver != 3 && ver != 4 ) {
Jakub Jelinek 0332e1
          ML_(symerr)( di, True,
Jakub Jelinek 0332e1
-                      "Ignoring non-Dwarf2/3 block in .debug_info" );
Jakub Jelinek 0332e1
+                      "Ignoring non-Dwarf2/3/4 block in .debug_info" );
Jakub Jelinek 0332e1
          continue;
Jakub Jelinek 0332e1
       }
Jakub Jelinek 0332e1
       
Jakub Jelinek 0332e1
@@ -3705,8 +3763,8 @@ void ML_(read_callframe_info_dwarf3)
Jakub Jelinek 0332e1
             VG_(printf)("cie.version     = %d\n", (Int)cie_version);
Jakub Jelinek 0332e1
          if (di->ddump_frames)
Jakub Jelinek 0332e1
             VG_(printf)("  Version:               %d\n", (Int)cie_version);
Jakub Jelinek 0332e1
-         if (cie_version != 1 && cie_version != 3) {
Jakub Jelinek 0332e1
-            how = "unexpected CIE version (not 1 nor 3)";
Jakub Jelinek 0332e1
+         if (cie_version != 1 && cie_version != 3 && cie_version != 4) {
Jakub Jelinek 0332e1
+            how = "unexpected CIE version (not 1 nor 3 nor 4)";
Jakub Jelinek 0332e1
             goto bad;
Jakub Jelinek 0332e1
          }
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
@@ -3722,6 +3780,19 @@ void ML_(read_callframe_info_dwarf3)
Jakub Jelinek 0332e1
             cie_augmentation += 2;
Jakub Jelinek 0332e1
          }
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
+         if (cie_version >= 4) {
Jakub Jelinek 0332e1
+            if (read_UChar(data) != sizeof(Addr)) {
Jakub Jelinek 0332e1
+               how = "unexpected address size";
Jakub Jelinek 0332e1
+               goto bad;
Jakub Jelinek 0332e1
+            }
Jakub Jelinek 0332e1
+            data += sizeof(UChar);
Jakub Jelinek 0332e1
+            if (read_UChar(data) != 0) {
Jakub Jelinek 0332e1
+               how = "unexpected non-zero segment size";
Jakub Jelinek 0332e1
+               goto bad;
Jakub Jelinek 0332e1
+            }
Jakub Jelinek 0332e1
+            data += sizeof(UChar);
Jakub Jelinek 0332e1
+         }
Jakub Jelinek 0332e1
+
Jakub Jelinek 0332e1
          the_CIEs[this_CIE].code_a_f = read_leb128( data, &nbytes, 0);
Jakub Jelinek 0332e1
          data += nbytes;
Jakub Jelinek 0332e1
          if (di->trace_cfi) 
Jakub Jelinek 0332e1
--- valgrind/coregrind/m_debuginfo/readdwarf3.c.jj	2010-04-07 11:10:52.000000000 +0200
Jakub Jelinek 0332e1
+++ valgrind/coregrind/m_debuginfo/readdwarf3.c	2010-04-07 12:48:07.000000000 +0200
Jakub Jelinek 0332e1
@@ -1,6 +1,6 @@
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
 /*--------------------------------------------------------------------*/
Jakub Jelinek 0332e1
-/*--- Read DWARF3 ".debug_info" sections (DIE trees).              ---*/
Jakub Jelinek 0332e1
+/*--- Read DWARF3/4 ".debug_info" sections (DIE trees).            ---*/
Jakub Jelinek 0332e1
 /*---                                                 readdwarf3.c ---*/
Jakub Jelinek 0332e1
 /*--------------------------------------------------------------------*/
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
@@ -387,7 +387,7 @@ typedef
Jakub Jelinek 0332e1
       void (*barf)( HChar* ) __attribute__((noreturn));
Jakub Jelinek 0332e1
       /* Is this 64-bit DWARF ? */
Jakub Jelinek 0332e1
       Bool   is_dw64;
Jakub Jelinek 0332e1
-      /* Which DWARF version ?  (2 or 3) */
Jakub Jelinek 0332e1
+      /* Which DWARF version ?  (2, 3 or 4) */
Jakub Jelinek 0332e1
       UShort version;
Jakub Jelinek 0332e1
       /* Length of this Compilation Unit, as stated in the
Jakub Jelinek 0332e1
          .unit_length :: InitialLength field of the CU Header.
Jakub Jelinek 0332e1
@@ -805,8 +805,8 @@ void parse_CU_Header ( /*OUT*/CUConst* c
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
    /* version */
Jakub Jelinek 0332e1
    cc->version = get_UShort( c );
Jakub Jelinek 0332e1
-   if (cc->version != 2 && cc->version != 3)
Jakub Jelinek 0332e1
-      cc->barf( "parse_CU_Header: is neither DWARF2 nor DWARF3" );
Jakub Jelinek 0332e1
+   if (cc->version != 2 && cc->version != 3 && cc->version != 4)
Jakub Jelinek 0332e1
+      cc->barf( "parse_CU_Header: is neither DWARF2 nor DWARF3 nor DWARF4" );
Jakub Jelinek 0332e1
    TRACE_D3("   Version:       %d\n", (Int)cc->version );
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
    /* debug_abbrev_offset */
Jakub Jelinek 0332e1
@@ -984,11 +984,21 @@ void get_Form_contents ( /*OUT*/ULong* c
Jakub Jelinek 0332e1
          *ctsSzB = 8;
Jakub Jelinek 0332e1
          TRACE_D3("%llu", *cts);
Jakub Jelinek 0332e1
          break;
Jakub Jelinek 0332e1
+      case DW_FORM_sec_offset:
Jakub Jelinek 0332e1
+         *cts = (ULong)get_Dwarfish_UWord( c, cc->is_dw64 );
Jakub Jelinek 0332e1
+         *ctsSzB = cc->is_dw64 ? 8 : 4;
Jakub Jelinek 0332e1
+         TRACE_D3("%llu", *cts);
Jakub Jelinek 0332e1
+         break;
Jakub Jelinek 0332e1
       case DW_FORM_sdata:
Jakub Jelinek 0332e1
          *cts = (ULong)(Long)get_SLEB128(c);
Jakub Jelinek 0332e1
          *ctsSzB = 8;
Jakub Jelinek 0332e1
          TRACE_D3("%lld", (Long)*cts);
Jakub Jelinek 0332e1
          break;
Jakub Jelinek 0332e1
+      case DW_FORM_udata:
Jakub Jelinek 0332e1
+         *cts = (ULong)(Long)get_ULEB128(c);
Jakub Jelinek 0332e1
+         *ctsSzB = 8;
Jakub Jelinek 0332e1
+         TRACE_D3("%llu", (Long)*cts);
Jakub Jelinek 0332e1
+         break;
Jakub Jelinek 0332e1
       case DW_FORM_addr:
Jakub Jelinek 0332e1
          /* note, this is a hack.  DW_FORM_addr is defined as getting
Jakub Jelinek 0332e1
             a word the size of the target machine as defined by the
Jakub Jelinek 0332e1
@@ -1055,6 +1065,22 @@ void get_Form_contents ( /*OUT*/ULong* c
Jakub Jelinek 0332e1
          *ctsMemSzB = 1 + (ULong)VG_(strlen)(str);
Jakub Jelinek 0332e1
          break;
Jakub Jelinek 0332e1
       }
Jakub Jelinek 0332e1
+      case DW_FORM_ref1: {
Jakub Jelinek 0332e1
+         UChar  u8 = get_UChar(c);
Jakub Jelinek 0332e1
+         UWord res = cc->cu_start_offset + (UWord)u8;
Jakub Jelinek 0332e1
+         *cts = (ULong)res;
Jakub Jelinek 0332e1
+         *ctsSzB = sizeof(UWord);
Jakub Jelinek 0332e1
+         TRACE_D3("<%lx>", res);
Jakub Jelinek 0332e1
+         break;
Jakub Jelinek 0332e1
+      }
Jakub Jelinek 0332e1
+      case DW_FORM_ref2: {
Jakub Jelinek 0332e1
+         UShort  u16 = get_UShort(c);
Jakub Jelinek 0332e1
+         UWord res = cc->cu_start_offset + (UWord)u16;
Jakub Jelinek 0332e1
+         *cts = (ULong)res;
Jakub Jelinek 0332e1
+         *ctsSzB = sizeof(UWord);
Jakub Jelinek 0332e1
+         TRACE_D3("<%lx>", res);
Jakub Jelinek 0332e1
+         break;
Jakub Jelinek 0332e1
+      }
Jakub Jelinek 0332e1
       case DW_FORM_ref4: {
Jakub Jelinek 0332e1
          UInt  u32 = get_UInt(c);
Jakub Jelinek 0332e1
          UWord res = cc->cu_start_offset + (UWord)u32;
Jakub Jelinek 0332e1
@@ -1063,6 +1089,22 @@ void get_Form_contents ( /*OUT*/ULong* c
Jakub Jelinek 0332e1
          TRACE_D3("<%lx>", res);
Jakub Jelinek 0332e1
          break;
Jakub Jelinek 0332e1
       }
Jakub Jelinek 0332e1
+      case DW_FORM_ref8: {
Jakub Jelinek 0332e1
+         ULong  u64 = get_ULong(c);
Jakub Jelinek 0332e1
+         UWord res = cc->cu_start_offset + (UWord)u64;
Jakub Jelinek 0332e1
+         *cts = (ULong)res;
Jakub Jelinek 0332e1
+         *ctsSzB = sizeof(UWord);
Jakub Jelinek 0332e1
+         TRACE_D3("<%lx>", res);
Jakub Jelinek 0332e1
+         break;
Jakub Jelinek 0332e1
+      }
Jakub Jelinek 0332e1
+      case DW_FORM_ref_udata: {
Jakub Jelinek 0332e1
+         ULong  u64 = get_ULEB128(c);
Jakub Jelinek 0332e1
+         UWord res = cc->cu_start_offset + (UWord)u64;
Jakub Jelinek 0332e1
+         *cts = (ULong)res;
Jakub Jelinek 0332e1
+         *ctsSzB = sizeof(UWord);
Jakub Jelinek 0332e1
+         TRACE_D3("<%lx>", res);
Jakub Jelinek 0332e1
+         break;
Jakub Jelinek 0332e1
+      }
Jakub Jelinek 0332e1
       case DW_FORM_flag: {
Jakub Jelinek 0332e1
          UChar u8 = get_UChar(c);
Jakub Jelinek 0332e1
          TRACE_D3("%u", (UInt)u8);
Jakub Jelinek 0332e1
@@ -1070,6 +1112,11 @@ void get_Form_contents ( /*OUT*/ULong* c
Jakub Jelinek 0332e1
          *ctsSzB = 1;
Jakub Jelinek 0332e1
          break;
Jakub Jelinek 0332e1
       }
Jakub Jelinek 0332e1
+      case DW_FORM_flag_present:
Jakub Jelinek 0332e1
+         TRACE_D3("1");
Jakub Jelinek 0332e1
+         *cts = 1;
Jakub Jelinek 0332e1
+         *ctsSzB = 1;
Jakub Jelinek 0332e1
+         break;
Jakub Jelinek 0332e1
       case DW_FORM_block1: {
Jakub Jelinek 0332e1
          ULong  u64b;
Jakub Jelinek 0332e1
          ULong  u64 = (ULong)get_UChar(c);
Jakub Jelinek 0332e1
@@ -1096,6 +1143,50 @@ void get_Form_contents ( /*OUT*/ULong* c
Jakub Jelinek 0332e1
          *ctsMemSzB = (UWord)u64;
Jakub Jelinek 0332e1
          break;
Jakub Jelinek 0332e1
       }
Jakub Jelinek 0332e1
+      case DW_FORM_block4: {
Jakub Jelinek 0332e1
+         ULong  u64b;
Jakub Jelinek 0332e1
+         ULong  u64 = (ULong)get_UInt(c);
Jakub Jelinek 0332e1
+         UChar* block = get_address_of_Cursor(c);
Jakub Jelinek 0332e1
+         TRACE_D3("%llu byte block: ", u64);
Jakub Jelinek 0332e1
+         for (u64b = u64; u64b > 0; u64b--) {
Jakub Jelinek 0332e1
+            UChar u8 = get_UChar(c);
Jakub Jelinek 0332e1
+            TRACE_D3("%x ", (UInt)u8);
Jakub Jelinek 0332e1
+         }
Jakub Jelinek 0332e1
+         *cts = (ULong)(UWord)block;
Jakub Jelinek 0332e1
+         *ctsMemSzB = (UWord)u64;
Jakub Jelinek 0332e1
+         break;
Jakub Jelinek 0332e1
+      }
Jakub Jelinek 0332e1
+      case DW_FORM_exprloc:
Jakub Jelinek 0332e1
+      case DW_FORM_block: {
Jakub Jelinek 0332e1
+         ULong  u64b;
Jakub Jelinek 0332e1
+         ULong  u64 = (ULong)get_ULEB128(c);
Jakub Jelinek 0332e1
+         UChar* block = get_address_of_Cursor(c);
Jakub Jelinek 0332e1
+         TRACE_D3("%llu byte block: ", u64);
Jakub Jelinek 0332e1
+         for (u64b = u64; u64b > 0; u64b--) {
Jakub Jelinek 0332e1
+            UChar u8 = get_UChar(c);
Jakub Jelinek 0332e1
+            TRACE_D3("%x ", (UInt)u8);
Jakub Jelinek 0332e1
+         }
Jakub Jelinek 0332e1
+         *cts = (ULong)(UWord)block;
Jakub Jelinek 0332e1
+         *ctsMemSzB = (UWord)u64;
Jakub Jelinek 0332e1
+         break;
Jakub Jelinek 0332e1
+      }
Jakub Jelinek 0332e1
+      case DW_FORM_ref_sig8: {
Jakub Jelinek 0332e1
+         ULong  u64b;
Jakub Jelinek 0332e1
+         UChar* block = get_address_of_Cursor(c);
Jakub Jelinek 0332e1
+         TRACE_D3("8 byte signature: ");
Jakub Jelinek 0332e1
+         for (u64b = 8; u64b > 0; u64b--) {
Jakub Jelinek 0332e1
+            UChar u8 = get_UChar(c);
Jakub Jelinek 0332e1
+            TRACE_D3("%x ", (UInt)u8);
Jakub Jelinek 0332e1
+         }
Jakub Jelinek 0332e1
+         *cts = (ULong)(UWord)block;
Jakub Jelinek 0332e1
+         *ctsMemSzB = 8;
Jakub Jelinek 0332e1
+         break;
Jakub Jelinek 0332e1
+      }
Jakub Jelinek 0332e1
+      case DW_FORM_indirect:
Jakub Jelinek 0332e1
+         get_Form_contents (cts, ctsSzB, ctsMemSzB, cc, c, td3,
Jakub Jelinek 0332e1
+                            (DW_FORM)get_ULEB128(c));
Jakub Jelinek 0332e1
+         return;
Jakub Jelinek 0332e1
+
Jakub Jelinek 0332e1
       default:
Jakub Jelinek 0332e1
          VG_(printf)(
Jakub Jelinek 0332e1
             "get_Form_contents: unhandled %d (%s) at <%lx>\n",
Jakub Jelinek 0332e1
@@ -1322,11 +1413,13 @@ void read_filename_table( /*MOD*/D3VarPa
Jakub Jelinek 0332e1
       get_Initial_Length( &is_dw64, &c,
Jakub Jelinek 0332e1
            "read_filename_table: invalid initial-length field" );
Jakub Jelinek 0332e1
    version = get_UShort( &c );
Jakub Jelinek 0332e1
-   if (version != 2 && version != 3)
Jakub Jelinek 0332e1
-     cc->barf("read_filename_table: Only DWARF version 2 and 3 line info "
Jakub Jelinek 0332e1
+   if (version != 2 && version != 3 && version != 4)
Jakub Jelinek 0332e1
+     cc->barf("read_filename_table: Only DWARF version 2, 3 and 4 line info "
Jakub Jelinek 0332e1
               "is currently supported.");
Jakub Jelinek 0332e1
    /*header_length              = (ULong)*/ get_Dwarfish_UWord( &c, is_dw64 );
Jakub Jelinek 0332e1
    /*minimum_instruction_length = */ get_UChar( &c );
Jakub Jelinek 0332e1
+   if (version >= 4)
Jakub Jelinek 0332e1
+      /*maximum_operations_per_insn = */ get_UChar( &c );
Jakub Jelinek 0332e1
    /*default_is_stmt            = */ get_UChar( &c );
Jakub Jelinek 0332e1
    /*line_base                  = (Char)*/ get_UChar( &c );
Jakub Jelinek 0332e1
    /*line_range                 = */ get_UChar( &c );
Jakub Jelinek 0332e1
@@ -2025,7 +2118,7 @@ static void parse_type_DIE ( /*MOD*/XArr
Jakub Jelinek 0332e1
             case DW_LANG_C89: case DW_LANG_C:
Jakub Jelinek 0332e1
             case DW_LANG_C_plus_plus: case DW_LANG_ObjC:
Jakub Jelinek 0332e1
             case DW_LANG_ObjC_plus_plus: case DW_LANG_UPC:
Jakub Jelinek 0332e1
-            case DW_LANG_Upc:
Jakub Jelinek 0332e1
+            case DW_LANG_Upc: case DW_LANG_C99:
Jakub Jelinek 0332e1
                parser->language = 'C'; break;
Jakub Jelinek 0332e1
             case DW_LANG_Fortran77: case DW_LANG_Fortran90:
Jakub Jelinek 0332e1
             case DW_LANG_Fortran95:
Jakub Jelinek 0332e1
@@ -2033,8 +2126,8 @@ static void parse_type_DIE ( /*MOD*/XArr
Jakub Jelinek 0332e1
             case DW_LANG_Ada83: case DW_LANG_Cobol74:
Jakub Jelinek 0332e1
             case DW_LANG_Cobol85: case DW_LANG_Pascal83:
Jakub Jelinek 0332e1
             case DW_LANG_Modula2: case DW_LANG_Java:
Jakub Jelinek 0332e1
-            case DW_LANG_C99: case DW_LANG_Ada95:
Jakub Jelinek 0332e1
-            case DW_LANG_PLI: case DW_LANG_D:
Jakub Jelinek 0332e1
+            case DW_LANG_Ada95: case DW_LANG_PLI:
Jakub Jelinek 0332e1
+            case DW_LANG_D: case DW_LANG_Python:
Jakub Jelinek 0332e1
             case DW_LANG_Mips_Assembler:
Jakub Jelinek 0332e1
                parser->language = '?'; break;
Jakub Jelinek 0332e1
             default:
Jakub Jelinek 0332e1
--- valgrind/coregrind/m_debuginfo/priv_d3basics.h.jj	2010-04-07 11:10:52.000000000 +0200
Jakub Jelinek 0332e1
+++ valgrind/coregrind/m_debuginfo/priv_d3basics.h	2010-04-07 11:50:45.000000000 +0200
Jakub Jelinek 0332e1
@@ -104,6 +104,10 @@ typedef enum 
Jakub Jelinek 0332e1
     DW_TAG_imported_unit = 0x3d,
Jakub Jelinek 0332e1
     DW_TAG_condition = 0x3f,
Jakub Jelinek 0332e1
     DW_TAG_shared_type = 0x40,
Jakub Jelinek 0332e1
+    /* DWARF 4.  */
Jakub Jelinek 0332e1
+    DW_TAG_type_unit = 0x41,
Jakub Jelinek 0332e1
+    DW_TAG_rvalue_reference_type = 0x42,
Jakub Jelinek 0332e1
+    DW_TAG_template_alias = 0x43,
Jakub Jelinek 0332e1
     /* SGI/MIPS Extensions.  */
Jakub Jelinek 0332e1
     DW_TAG_MIPS_loop = 0x4081,
Jakub Jelinek 0332e1
     /* HP extensions.  See: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz .  */
Jakub Jelinek 0332e1
@@ -158,6 +162,8 @@ typedef enum dwarf_source_language
Jakub Jelinek 0332e1
     DW_LANG_ObjC_plus_plus = 0x0011,
Jakub Jelinek 0332e1
     DW_LANG_UPC = 0x0012,
Jakub Jelinek 0332e1
     DW_LANG_D = 0x0013,
Jakub Jelinek 0332e1
+    /* DWARF 4.  */
Jakub Jelinek 0332e1
+    DW_LANG_Python = 0x0014,
Jakub Jelinek 0332e1
     /* MIPS.  */
Jakub Jelinek 0332e1
     DW_LANG_Mips_Assembler = 0x8001,
Jakub Jelinek 0332e1
     /* UPC.  */
Jakub Jelinek 0332e1
@@ -188,7 +194,12 @@ typedef enum
Jakub Jelinek 0332e1
     DW_FORM_ref4 = 0x13,
Jakub Jelinek 0332e1
     DW_FORM_ref8 = 0x14,
Jakub Jelinek 0332e1
     DW_FORM_ref_udata = 0x15,
Jakub Jelinek 0332e1
-    DW_FORM_indirect = 0x16
Jakub Jelinek 0332e1
+    DW_FORM_indirect = 0x16,
Jakub Jelinek 0332e1
+    /* DWARF 4 values.  */
Jakub Jelinek 0332e1
+    DW_FORM_sec_offset = 0x17,
Jakub Jelinek 0332e1
+    DW_FORM_exprloc = 0x18,
Jakub Jelinek 0332e1
+    DW_FORM_flag_present = 0x19,
Jakub Jelinek 0332e1
+    DW_FORM_ref_sig8 = 0x20
Jakub Jelinek 0332e1
   }
Jakub Jelinek 0332e1
   DW_FORM;
Jakub Jelinek 0332e1
 
Jakub Jelinek 0332e1
@@ -285,6 +296,13 @@ typedef enum
Jakub Jelinek 0332e1
     DW_AT_elemental     = 0x66,
Jakub Jelinek 0332e1
     DW_AT_pure          = 0x67,
Jakub Jelinek 0332e1
     DW_AT_recursive     = 0x68,
Jakub Jelinek 0332e1
+    /* DWARF 4 values.  */
Jakub Jelinek 0332e1
+    DW_AT_signature       = 0x69,
Jakub Jelinek 0332e1
+    DW_AT_main_subprogram = 0x6a,
Jakub Jelinek 0332e1
+    DW_AT_data_bit_offset = 0x6b,
Jakub Jelinek 0332e1
+    DW_AT_const_expr      = 0x6c,
Jakub Jelinek 0332e1
+    DW_AT_enum_class      = 0x6d,
Jakub Jelinek 0332e1
+    DW_AT_linkage_name    = 0x6e,
Jakub Jelinek 0332e1
     /* SGI/MIPS extensions.  */
Jakub Jelinek 0332e1
     DW_AT_MIPS_fde = 0x2001,
Jakub Jelinek 0332e1
     DW_AT_MIPS_loop_begin = 0x2002,
Jakub Jelinek 0332e1
--- valgrind/coregrind/m_debuginfo/d3basics.c.jj	2010-04-07 11:10:52.000000000 +0200
Jakub Jelinek 0332e1
+++ valgrind/coregrind/m_debuginfo/d3basics.c	2010-04-07 11:50:45.000000000 +0200
Jakub Jelinek 0332e1
@@ -124,6 +124,10 @@ HChar* ML_(pp_DW_TAG) ( DW_TAG tag )
Jakub Jelinek 0332e1
       case DW_TAG_imported_unit:      return "DW_TAG_imported_unit";
Jakub Jelinek 0332e1
       case DW_TAG_condition:          return "DW_TAG_condition";
Jakub Jelinek 0332e1
       case DW_TAG_shared_type:        return "DW_TAG_shared_type";
Jakub Jelinek 0332e1
+      /* DWARF 4.  */
Jakub Jelinek 0332e1
+      case DW_TAG_type_unit:          return "DW_TAG_type_unit";
Jakub Jelinek 0332e1
+      case DW_TAG_rvalue_reference_type: return "DW_TAG_rvalue_reference_type";
Jakub Jelinek 0332e1
+      case DW_TAG_template_alias:     return "DW_TAG_template_alias";
Jakub Jelinek 0332e1
       /* SGI/MIPS Extensions.  */
Jakub Jelinek 0332e1
       case DW_TAG_MIPS_loop:          return "DW_TAG_MIPS_loop";
Jakub Jelinek 0332e1
       /* HP extensions.  See:
Jakub Jelinek 0332e1
@@ -172,6 +176,10 @@ HChar* ML_(pp_DW_FORM) ( DW_FORM form )
Jakub Jelinek 0332e1
       case DW_FORM_ref8:      return "DW_FORM_ref8";
Jakub Jelinek 0332e1
       case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
Jakub Jelinek 0332e1
       case DW_FORM_indirect:  return "DW_FORM_indirect";
Jakub Jelinek 0332e1
+      case DW_FORM_sec_offset:return "DW_FORM_sec_offset";
Jakub Jelinek 0332e1
+      case DW_FORM_exprloc:   return "DW_FORM_exprloc";
Jakub Jelinek 0332e1
+      case DW_FORM_flag_present:return "DW_FORM_flag_present";
Jakub Jelinek 0332e1
+      case DW_FORM_ref_sig8:  return "DW_FORM_ref_sig8";
Jakub Jelinek 0332e1
       default:                return "DW_FORM_???";
Jakub Jelinek 0332e1
    }
Jakub Jelinek 0332e1
 }
Jakub Jelinek 0332e1
@@ -269,6 +277,13 @@ HChar* ML_(pp_DW_AT) ( DW_AT attr )
Jakub Jelinek 0332e1
       case DW_AT_elemental: return "DW_AT_elemental";
Jakub Jelinek 0332e1
       case DW_AT_pure: return "DW_AT_pure";
Jakub Jelinek 0332e1
       case DW_AT_recursive: return "DW_AT_recursive";
Jakub Jelinek 0332e1
+      /* DWARF 4 values.  */
Jakub Jelinek 0332e1
+      case DW_AT_signature: return "DW_AT_signature";
Jakub Jelinek 0332e1
+      case DW_AT_main_subprogram: return "DW_AT_main_subprogram";
Jakub Jelinek 0332e1
+      case DW_AT_data_bit_offset: return "DW_AT_data_bit_offset";
Jakub Jelinek 0332e1
+      case DW_AT_const_expr: return "DW_AT_const_expr";
Jakub Jelinek 0332e1
+      case DW_AT_enum_class: return "DW_AT_enum_class";
Jakub Jelinek 0332e1
+      case DW_AT_linkage_name: return "DW_AT_linkage_name";
Jakub Jelinek 0332e1
       /* SGI/MIPS extensions.  */
Jakub Jelinek 0332e1
       /* case DW_AT_MIPS_fde: return "DW_AT_MIPS_fde"; */
Jakub Jelinek 0332e1
       /* DW_AT_MIPS_fde == DW_AT_HP_unmodifiable */