From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14808 invoked by alias); 20 Apr 2010 17:33:05 -0000 Received: (qmail 14768 invoked by uid 22791); 20 Apr 2010 17:33:02 -0000 X-SWARE-Spam-Status: No, hits=-5.4 required=5.0 tests=BAYES_00,KAM_STOCKGEN,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 20 Apr 2010 17:32:54 +0000 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o3KHWr8T015436 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 20 Apr 2010 13:32:53 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o3KHWqec008597; Tue, 20 Apr 2010 13:32:52 -0400 Received: from opsy.redhat.com (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id o3KHWpXM022694; Tue, 20 Apr 2010 13:32:51 -0400 Received: by opsy.redhat.com (Postfix, from userid 500) id 3C42F37979C; Tue, 20 Apr 2010 11:32:51 -0600 (MDT) From: Tom Tromey To: Jan Kratochvil Cc: gdb-patches@sourceware.org Subject: Re: RFC: add DWARF-4 features References: <20100419180809.GA4722@host0.dyn.jankratochvil.net> Reply-To: tromey@redhat.com Date: Tue, 20 Apr 2010 17:33:00 -0000 In-Reply-To: <20100419180809.GA4722@host0.dyn.jankratochvil.net> (Jan Kratochvil's message of "Mon, 19 Apr 2010 20:08:09 +0200") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-04/txt/msg00617.txt.bz2 >>>>> "Jan" == Jan Kratochvil writes: [...] Jan> I would prefer unified form of the expressions as an aid to the Jan> reader. Here is MINIMUM_INSTRUCTION_LENGTH preceding the rest of Jan> the expression while it is succeeding the rest of the expression in Jan> the patch chunk above. Thanks for your excellent review. I am committing the appended updated patch. Tom 2010-04-20 Tom Tromey * dwarf2-frame.c (decode_frame_entry_1): Handle CIE version 4. (struct dwarf2_cie) : New field. * dwarf2read.c (partial_read_comp_unit_head): Accept DWARF 4. (skip_one_die): Handle DW_FORM_flag_present, DW_FORM_sec_offset, DW_FORM_exprloc. (read_attribute_value): Handle DW_FORM_flag_present, DW_FORM_sec_offset, DW_FORM_exprloc. (dump_die_shallow): Likewise. (attr_form_is_section_offset): Handle DW_FORM_sec_offset. (dwarf2_const_value): Handle DW_FORM_exprloc. (attr_form_is_block): Likewise. (struct line_header) : New field. (dwarf_decode_line_header): Set new field. (dwarf_decode_lines): Handle new field. Index: dwarf2-frame.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2-frame.c,v retrieving revision 1.107 diff -u -r1.107 dwarf2-frame.c --- dwarf2-frame.c 24 Mar 2010 21:06:30 -0000 1.107 +++ dwarf2-frame.c 20 Apr 2010 17:32:08 -0000 @@ -85,6 +85,9 @@ /* The version recorded in the CIE. */ unsigned char version; + + /* The segment size. */ + unsigned char segment_size; }; struct dwarf2_cie_table @@ -1714,7 +1717,7 @@ /* Check version number. */ cie_version = read_1_byte (unit->abfd, buf); - if (cie_version != 1 && cie_version != 3) + if (cie_version != 1 && cie_version != 3 && cie_version != 4) return NULL; cie->version = cie_version; buf += 1; @@ -1738,6 +1741,20 @@ augmentation += 2; } + if (cie->version >= 4) + { + /* FIXME: check that this is the same as from the CU header. */ + cie->addr_size = read_1_byte (unit->abfd, buf); + ++buf; + cie->segment_size = read_1_byte (unit->abfd, buf); + ++buf; + } + else + { + cie->addr_size = gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT; + cie->segment_size = 0; + } + cie->code_alignment_factor = read_unsigned_leb128 (unit->abfd, buf, &bytes_read); buf += bytes_read; Index: dwarf2read.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.378 diff -u -r1.378 dwarf2read.c --- dwarf2read.c 2 Apr 2010 15:21:47 -0000 1.378 +++ dwarf2read.c 20 Apr 2010 17:32:09 -0000 @@ -396,6 +396,7 @@ unsigned short version; unsigned int header_length; unsigned char minimum_instruction_length; + unsigned char maximum_ops_per_instruction; unsigned char default_is_stmt; int line_base; unsigned char line_range; @@ -1488,10 +1489,10 @@ info_ptr = read_comp_unit_head (header, info_ptr, abfd); - if (header->version != 2 && header->version != 3) + if (header->version != 2 && header->version != 3 && header->version != 4) error (_("Dwarf Error: wrong version in compilation unit header " - "(is %d, should be %d) [in module %s]"), header->version, - 2, bfd_get_filename (abfd)); + "(is %d, should be 2, 3, or 4) [in module %s]"), header->version, + bfd_get_filename (abfd)); if (header->abbrev_offset >= dwarf2_per_objfile->abbrev.size) error (_("Dwarf Error: bad offset (0x%lx) in compilation unit header " @@ -2776,6 +2777,8 @@ case DW_FORM_flag: info_ptr += 1; break; + case DW_FORM_flag_present: + break; case DW_FORM_data2: case DW_FORM_ref2: info_ptr += 2; @@ -2793,9 +2796,11 @@ read_string (abfd, info_ptr, &bytes_read); info_ptr += bytes_read; break; + case DW_FORM_sec_offset: case DW_FORM_strp: info_ptr += cu->header.offset_size; break; + case DW_FORM_exprloc: case DW_FORM_block: info_ptr += read_unsigned_leb128 (abfd, info_ptr, &bytes_read); info_ptr += bytes_read; @@ -7129,6 +7134,10 @@ DW_UNSND (attr) = read_8_bytes (abfd, info_ptr); info_ptr += 8; break; + case DW_FORM_sec_offset: + DW_UNSND (attr) = read_offset (abfd, info_ptr, &cu->header, &bytes_read); + info_ptr += bytes_read; + break; case DW_FORM_string: DW_STRING (attr) = read_string (abfd, info_ptr, &bytes_read); DW_STRING_IS_CANONICAL (attr) = 0; @@ -7140,6 +7149,7 @@ DW_STRING_IS_CANONICAL (attr) = 0; info_ptr += bytes_read; break; + case DW_FORM_exprloc: case DW_FORM_block: blk = dwarf_alloc_block (cu); blk->size = read_unsigned_leb128 (abfd, info_ptr, &bytes_read); @@ -7164,6 +7174,9 @@ DW_UNSND (attr) = read_1_byte (abfd, info_ptr); info_ptr += 1; break; + case DW_FORM_flag_present: + DW_UNSND (attr) = 1; + break; case DW_FORM_sdata: DW_SND (attr) = read_signed_leb128 (abfd, info_ptr, &bytes_read); info_ptr += bytes_read; @@ -7680,7 +7693,7 @@ /* Return non-zero iff the attribute NAME is defined for the given DIE, and holds a non-zero value. This function should only be used for - DW_FORM_flag attributes. */ + DW_FORM_flag or DW_FORM_flag_present attributes. */ static int dwarf2_flag_true_p (struct die_info *die, unsigned name, struct dwarf2_cu *cu) @@ -7862,6 +7875,21 @@ line_ptr += offset_size; lh->minimum_instruction_length = read_1_byte (abfd, line_ptr); line_ptr += 1; + if (lh->version >= 4) + { + lh->maximum_ops_per_instruction = read_1_byte (abfd, line_ptr); + line_ptr += 1; + } + else + lh->maximum_ops_per_instruction = 1; + + if (lh->maximum_ops_per_instruction == 0) + { + lh->maximum_ops_per_instruction = 1; + complaint (&symfile_complaints, + _("invalid maximum_ops_per_instruction in `.debug_line' section")); + } + lh->default_is_stmt = read_1_byte (abfd, line_ptr); line_ptr += 1; lh->line_base = read_1_signed_byte (abfd, line_ptr); @@ -8010,6 +8038,7 @@ int basic_block = 0; int end_sequence = 0; CORE_ADDR addr; + unsigned char op_index = 0; if (!decode_for_pst_p && lh->num_file_names >= file) { @@ -8041,12 +8070,17 @@ { /* Special operand. */ adj_opcode = op_code - lh->opcode_base; - address += (adj_opcode / lh->line_range) - * lh->minimum_instruction_length; + address += (((op_index + (adj_opcode / lh->line_range)) + / lh->maximum_ops_per_instruction) + * lh->minimum_instruction_length); + op_index = ((op_index + (adj_opcode / lh->line_range)) + % lh->maximum_ops_per_instruction); line += lh->line_base + (adj_opcode % lh->line_range); if (lh->num_file_names < file || file == 0) dwarf2_debug_line_missing_file_complaint (); - else + /* For now we ignore lines not starting on an + instruction boundary. */ + else if (op_index == 0) { lh->file_names[file - 1].included_p = 1; if (!decode_for_pst_p && is_stmt) @@ -8081,6 +8115,7 @@ break; case DW_LNE_set_address: address = read_address (abfd, line_ptr, cu, &bytes_read); + op_index = 0; line_ptr += bytes_read; address += baseaddr; break; @@ -8146,9 +8181,17 @@ basic_block = 0; break; case DW_LNS_advance_pc: - address += lh->minimum_instruction_length - * read_unsigned_leb128 (abfd, line_ptr, &bytes_read); - line_ptr += bytes_read; + { + CORE_ADDR adjust + = read_unsigned_leb128 (abfd, line_ptr, &bytes_read); + + address += (((op_index + adjust) + / lh->maximum_ops_per_instruction) + * lh->minimum_instruction_length); + op_index = ((op_index + adjust) + % lh->maximum_ops_per_instruction); + line_ptr += bytes_read; + } break; case DW_LNS_advance_line: line += read_signed_leb128 (abfd, line_ptr, &bytes_read); @@ -8195,11 +8238,19 @@ instruction length since special opcode 255 would have scaled the the increment. */ case DW_LNS_const_add_pc: - address += (lh->minimum_instruction_length - * ((255 - lh->opcode_base) / lh->line_range)); + { + CORE_ADDR adjust = (255 - lh->opcode_base) / lh->line_range; + + address += (((op_index + adjust) + / lh->maximum_ops_per_instruction) + * lh->minimum_instruction_length); + op_index = ((op_index + adjust) + % lh->maximum_ops_per_instruction); + } break; case DW_LNS_fixed_advance_pc: address += read_2_bytes (abfd, line_ptr); + op_index = 0; line_ptr += 2; break; default: @@ -8761,6 +8812,7 @@ case DW_FORM_block2: case DW_FORM_block4: case DW_FORM_block: + case DW_FORM_exprloc: blk = DW_BLOCK (attr); if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != blk->size) dwarf2_const_value_length_mismatch_complaint (SYMBOL_PRINT_NAME (sym), @@ -10308,6 +10360,10 @@ case DW_FORM_block1: fprintf_unfiltered (f, "block: size %d", DW_BLOCK (&die->attrs[i])->size); break; + case DW_FORM_exprloc: + fprintf_unfiltered (f, "expression: size %u", + DW_BLOCK (&die->attrs[i])->size); + break; case DW_FORM_ref1: case DW_FORM_ref2: case DW_FORM_ref4: @@ -10323,6 +10379,10 @@ fprintf_unfiltered (f, "constant: %s", pulongest (DW_UNSND (&die->attrs[i]))); break; + case DW_FORM_sec_offset: + fprintf_unfiltered (f, "section offset: %s", + pulongest (DW_UNSND (&die->attrs[i]))); + break; case DW_FORM_sig8: if (DW_SIGNATURED_TYPE (&die->attrs[i]) != NULL) fprintf_unfiltered (f, "signatured type, offset: 0x%x", @@ -10343,6 +10403,9 @@ else fprintf_unfiltered (f, "flag: FALSE"); break; + case DW_FORM_flag_present: + fprintf_unfiltered (f, "flag: TRUE"); + break; case DW_FORM_indirect: /* the reader will have reduced the indirect form to the "base form" so this form should not occur */ @@ -11520,7 +11583,8 @@ attr->form == DW_FORM_block1 || attr->form == DW_FORM_block2 || attr->form == DW_FORM_block4 - || attr->form == DW_FORM_block); + || attr->form == DW_FORM_block + || attr->form == DW_FORM_exprloc); } /* Return non-zero if ATTR's value is a section offset --- classes @@ -11535,7 +11599,8 @@ attr_form_is_section_offset (struct attribute *attr) { return (attr->form == DW_FORM_data4 - || attr->form == DW_FORM_data8); + || attr->form == DW_FORM_data8 + || attr->form == DW_FORM_sec_offset); }