From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3812 invoked by alias); 12 Nov 2001 21:12:39 -0000 Mailing-List: contact gdb-patches-help@sourceware.cygnus.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 31723 invoked from network); 12 Nov 2001 20:58:43 -0000 Received: from unknown (HELO zwingli.cygnus.com) (208.245.165.35) by sourceware.cygnus.com with SMTP; 12 Nov 2001 20:58:43 -0000 Received: by zwingli.cygnus.com (Postfix, from userid 442) id C8E0C5E9D8; Mon, 12 Nov 2001 15:59:57 -0500 (EST) To: Geoffrey Keating Cc: gdb-patches@sources.redhat.com, binutils@sources.redhat.com Subject: Re: properly handle extensions to DWARF 2 line number information References: <200111111226.fABCQMv05908@thief.cygnus.com> From: Jim Blandy Date: Thu, 01 Nov 2001 18:24:00 -0000 In-Reply-To: Geoffrey Keating's message of Sun, 11 Nov 2001 04:26:22 -0800 Message-ID: X-Mailer: Gnus v5.3/Emacs 19.34 X-SW-Source: 2001-11/txt/msg00015.txt.bz2 The GDB portion of this patch is approved for the trunk. Geoffrey Keating writes: > > > The forthcoming DWARF 3 standard extends the DWARF 2 line number > information in a backwards-compatible way, by increasing opcode_base > and defining new standard opcodes. > > That is, it's backwards-compatible if the DWARF 2 reader properly > ignores unknown standard opcodes. Unfortunately, the ones in BFD, > GDB, and binutils don't; they expect that any opcodes they don't know > about must be special opcodes. > > It would be good to get this patch into the next GDB release (5.1?), > because I hope soon to implement one of the extensions in GAS, the > DW_LNS_set_isa opcode, and the effect of this bug is that GDB can't > understand any files in which this opcode is used. > > This has been tested on x86-linux using target 'unix/-gdwarf-2'. It > has also been tested with a file with the DW_LNS_set_isa included (the > file was generated by hand). > > OK to commit? I think I need approval from both GDB and binutils > maintainers. > > -- > Geoff Keating > > ===File ~/patches/gdb-lineextend.patch====================== > Index: bfd/ChangeLog > 2001-11-11 Geoffrey Keating > > * dwarf2.c (decode_line_info): Properly deal with unknown standard > opcodes. > > Index: binutils/ChangeLog > 2001-11-11 Geoffrey Keating > > * readelf.c (display_debug_lines): Deal with unknown standard > opcodes. Handle DW_LNS_set_prologue_end, DW_LNS_set_epilogue_begin, > DW_LNS_set_isa. > > Index: gdb/ChangeLog > 2001-11-11 Geoffrey Keating > > * dwarf2read.c (dwarf_decode_lines): Properly deal with > unknown standard opcodes. > > Index: include/elf/ChangeLog > 2001-11-11 Geoffrey Keating > > * dwarf2.h (dwarf_line_number_ops): Add DWARF 3 opcodes. > > Index: bfd/dwarf2.c > =================================================================== > RCS file: /cvs/src/src/bfd/dwarf2.c,v > retrieving revision 1.24 > diff -p -u -p -r1.24 dwarf2.c > --- dwarf2.c 2001/10/06 10:01:09 1.24 > +++ dwarf2.c 2001/11/11 11:42:13 > @@ -979,7 +979,22 @@ decode_line_info (unit, stash) > op_code = read_1_byte (abfd, line_ptr); > line_ptr += 1; > > - switch (op_code) > + if (op_code >= lh.opcode_base) > + { /* Special operand. */ > + adj_opcode = op_code - lh.opcode_base; > + address += (adj_opcode / lh.line_range) > + * lh.minimum_instruction_length; > + line += lh.line_base + (adj_opcode % lh.line_range); > + /* Append row to matrix using current values. */ > + add_line_info (table, address, filename, line, column, 0); > + basic_block = 1; > + if (need_low_pc) > + { > + need_low_pc = 0; > + low_pc = address; > + } > + } > + else switch (op_code) > { > case DW_LNS_extended_op: > line_ptr += 1; /* Ignore length. */ > @@ -1079,19 +1094,15 @@ decode_line_info (unit, stash) > address += read_2_bytes (abfd, line_ptr); > line_ptr += 2; > break; > - default: /* Special operand. */ > - adj_opcode = op_code - lh.opcode_base; > - address += (adj_opcode / lh.line_range) > - * lh.minimum_instruction_length; > - line += lh.line_base + (adj_opcode % lh.line_range); > - /* Append row to matrix using current values. */ > - add_line_info (table, address, filename, line, column, 0); > - basic_block = 1; > - if (need_low_pc) > - { > - need_low_pc = 0; > - low_pc = address; > - } > + default: > + { /* Unknown standard opcode, ignore it. */ > + int i; > + for (i = 0; i < lh.standard_opcode_lengths[op_code]; i++) > + { > + (void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read); > + line_ptr += bytes_read; > + } > + } > } > } > } > Index: binutils/readelf.c > =================================================================== > RCS file: /cvs/src/src/binutils/readelf.c,v > retrieving revision 1.131 > diff -p -u -p -r1.131 readelf.c > --- readelf.c 2001/11/10 00:55:48 1.131 > +++ readelf.c 2001/11/11 11:42:14 > @@ -5888,8 +5888,20 @@ display_debug_lines (section, start, fil > > op_code = * data ++; > > - switch (op_code) > + if (op_code >= info.li_opcode_base) > { > + op_code -= info.li_opcode_base; > + adv = (op_code / info.li_line_range) * info.li_min_insn_length; > + state_machine_regs.address += adv; > + printf (_(" Special opcode %d: advance Address by %d to 0x%lx"), > + op_code, adv, state_machine_regs.address); > + adv = (op_code % info.li_line_range) + info.li_line_base; > + state_machine_regs.line += adv; > + printf (_(" and Line by %d to %d\n"), > + adv, state_machine_regs.line); > + } > + else switch (op_code) > + { > case DW_LNS_extended_op: > data += process_extended_line_op (data, info.li_default_is_stmt, > debug_line_pointer_size); > @@ -5958,20 +5970,36 @@ display_debug_lines (section, start, fil > adv, state_machine_regs.address); > break; > > + case DW_LNS_set_prologue_end: > + printf (_(" Set prologue_end to true\n")); > + break; > + > + case DW_LNS_set_epilogue_begin: > + printf (_(" Set epilogue_begin to true\n")); > + break; > + > + case DW_LNS_set_isa: > + adv = read_leb128 (data, & bytes_read, 0); > + data += bytes_read; > + printf (_(" Set ISA to %d\n"), adv); > + break; > + > default: > - op_code -= info.li_opcode_base; > - adv = (op_code / info.li_line_range) * info.li_min_insn_length; > - state_machine_regs.address += adv; > - printf (_(" Special opcode %d: advance Address by %d to 0x%lx"), > - op_code, adv, state_machine_regs.address); > - adv = (op_code % info.li_line_range) + info.li_line_base; > - state_machine_regs.line += adv; > - printf (_(" and Line by %d to %d\n"), > - adv, state_machine_regs.line); > + printf (_(" Unknown opcode %d with operands: "), op_code); > + { > + int i; > + for (i = standard_opcodes[op_code - 1]; i > 0 ; --i) > + { > + printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0), > + i == 1 ? "" : ", "); > + data += bytes_read; > + } > + putchar ('\n'); > + } > break; > } > } > - printf ("\n"); > + putchar ('\n'); > } > > return 1; > Index: gdb/dwarf2read.c > =================================================================== > RCS file: /cvs/src/src/gdb/dwarf2read.c,v > retrieving revision 1.33 > diff -p -u -p -r1.33 dwarf2read.c > --- dwarf2read.c 2001/11/06 23:38:14 1.33 > +++ dwarf2read.c 2001/11/11 11:42:16 > @@ -3963,7 +3963,18 @@ dwarf_decode_lines (unsigned int offset, > { > op_code = read_1_byte (abfd, line_ptr); > line_ptr += 1; > - switch (op_code) > + > + if (op_code >= lh.opcode_base) > + { /* Special operand. */ > + adj_opcode = op_code - lh.opcode_base; > + address += (adj_opcode / lh.line_range) > + * lh.minimum_instruction_length; > + line += lh.line_base + (adj_opcode % lh.line_range); > + /* append row to matrix using current values */ > + record_line (current_subfile, line, address); > + basic_block = 1; > + } > + else switch (op_code) > { > case DW_LNS_extended_op: > line_ptr += 1; /* ignore length */ > @@ -4061,14 +4072,15 @@ dwarf_decode_lines (unsigned int offset, > address += read_2_bytes (abfd, line_ptr); > line_ptr += 2; > break; > - default: /* special operand */ > - adj_opcode = op_code - lh.opcode_base; > - address += (adj_opcode / lh.line_range) > - * lh.minimum_instruction_length; > - line += lh.line_base + (adj_opcode % lh.line_range); > - /* append row to matrix using current values */ > - record_line (current_subfile, line, address); > - basic_block = 1; > + default: > + { /* Unknown standard opcode, ignore it. */ > + int i; > + for (i = 0; i < lh.standard_opcode_lengths[op_code]; i++) > + { > + (void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read); > + line_ptr += bytes_read; > + } > + } > } > } > } > Index: include/elf/dwarf2.h > =================================================================== > RCS file: /cvs/src/src/include/elf/dwarf2.h,v > retrieving revision 1.6 > diff -p -u -p -r1.6 dwarf2.h > --- dwarf2.h 2001/06/30 08:58:10 1.6 > +++ dwarf2.h 2001/11/11 11:42:18 > @@ -588,7 +588,11 @@ enum dwarf_line_number_ops > DW_LNS_negate_stmt = 6, > DW_LNS_set_basic_block = 7, > DW_LNS_const_add_pc = 8, > - DW_LNS_fixed_advance_pc = 9 > + DW_LNS_fixed_advance_pc = 9, > + /* DWARF 3 */ > + DW_LNS_set_prologue_end = 10, > + DW_LNS_set_epilogue_begin = 11, > + DW_LNS_set_isa = 12 > }; > > /* Line number extended opcodes. */ > ============================================================ >