[RFA/dwarf2] Small problem scanning line table for included files

Joel Brobecker brobecker@gnat.com
Sun Jul 25 15:11:00 GMT 2004


Hello,

I noticed that gdb.base/sep.exp fails with GCC 3.4. The attached
patch fixes it (the comment should explain how).

For the record, here is the line table generated by 3.4 for sep.c:

> The File Name Table:
>  Entry Dir     Time    Size    Name
>  1     0       0       0       sep-proc.c
>  2     0       0       0       sep.c
>
> Line Number Statements:
>  Extended opcode 2: set Address to 0x0
>  Advance Line by 23 to 24
>  Copy
>  Special opcode 90: advance Address by 6 to 0x6 and Line by 1 to 25
>  Special opcode 174: advance Address by 12 to 0x12 and Line by 1 to 26
>  Set File Name to entry 2 in the File Name Table
>  Special opcode 38: advance Address by 2 to 0x14 and Line by 5 to 31
>  Advance PC by constant 17 to 0x25
>  Special opcode 160: advance Address by 11 to 0x30 and Line by 1 to 32
>  Special opcode 76: advance Address by 5 to 0x35 and Line by 1 to 33
>  Special opcode 76: advance Address by 5 to 0x3a and Line by 1 to 34
>  Advance PC by 2 to 3c
>  Extended opcode 1: End of Sequence

And here is the line table generated by 3.2:

> The File Name Table:
>  Entry Dir     Time    Size    Name
>  1     0       0       0       sep.c
>  2     1       0       0       types.h
>  3     2       0       0       wchar.h
>  4     3       0       0       stddef.h
>  5     2       0       0       _G_config.h
>  6     2       0       0       gconv.h
>  7     2       0       0       libio.h
>  8     3       0       0       stdio.h
>  9     0       0       0       sep-proc.c
>  10    3       0       0       stdarg.h
>
> Line Number Statements:
>  Set File Name to entry 9 in the File Name Table
>  Extended opcode 2: set Address to 0x0
>  Advance Line by 23 to 24
>  Copy
>  Special opcode 90: advance Address by 6 to 0x6 and Line by 1 to 25
>  Special opcode 174: advance Address by 12 to 0x12 and Line by 1 to 26
>  Set File Name to entry 1 in the File Name Table
>  Special opcode 38: advance Address by 2 to 0x14 and Line by 5 to 31
>  Special opcode 230: advance Address by 16 to 0x24 and Line by 1 to 32
>  Special opcode 76: advance Address by 5 to 0x29 and Line by 1 to 33
>  Special opcode 76: advance Address by 5 to 0x2e and Line by 1 to 34
>  Advance PC by 2 to 30
>  Extended opcode 1: End of Sequence

The new line info with GCC 3.4 is much better, but tricks current GDB.

2004-07-25  Joel Brobecker  <brobecker@gnat.com>

        * dwarf2read.c (dwarf_decode_lines): Handle the case when a set_file
        instruction is not emitted for the first file, as it is implicit
        at the begining of the line number program.
        Fixes [D721-012].

Tested on x86-linux, fixes the 2 regressions in sep.exp.
OK to commit?

Thanks,
-- 
Joel
-------------- next part --------------
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.156
diff -u -p -r1.156 dwarf2read.c
--- dwarf2read.c	6 Jul 2004 19:29:30 -0000	1.156
+++ dwarf2read.c	25 Jul 2004 15:02:45 -0000
@@ -5926,6 +5926,18 @@ dwarf_decode_lines (struct line_header *
   CORE_ADDR baseaddr;
   struct objfile *objfile = cu->objfile;
   const int decode_for_pst_p = (pst != NULL);
+  
+  /* Normally, we detect the list of files that are really included by
+     scanning the LNP for DW_LNS_set_file.  However, the initial value
+     for the file register is 1, which means that the program is allowed
+     to omit the set_file instruction at the begining if the first
+     instructions refer to that file.  In order to detect that case,
+     we use this FIRST_SET_FILE_FOUND boolean that will be set as soon
+     as we encounter the a set_file instruction.  If, in the meantime,
+     we find any instruction that does change the address, line or
+     column registers, then it means that file 1 was indeed included.  */
+  int first_set_file_found = 0;
+  int file_one_included_p = 0;
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
@@ -5977,6 +5989,8 @@ dwarf_decode_lines (struct line_header *
 	          record_line (current_subfile, line, 
 	                       check_cu_functions (address, cu));
                 }
+             if (!first_set_file_found)
+               file_one_included_p = 1;
 	      basic_block = 1;
 	    }
 	  else switch (op_code)
@@ -5997,6 +6011,8 @@ dwarf_decode_lines (struct line_header *
 		  address = read_address (abfd, line_ptr, cu, &bytes_read);
 		  line_ptr += bytes_read;
 		  address += baseaddr;
+                 if (!first_set_file_found)
+                   file_one_included_p = 1;
 		  break;
 		case DW_LNE_define_file:
                   {
@@ -6028,15 +6044,21 @@ dwarf_decode_lines (struct line_header *
 	        record_line (current_subfile, line, 
 	                     check_cu_functions (address, cu));
 	      basic_block = 0;
+             if (!first_set_file_found)
+               file_one_included_p = 1;
 	      break;
 	    case DW_LNS_advance_pc:
 	      address += lh->minimum_instruction_length
 		* read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
 	      line_ptr += bytes_read;
+             if (!first_set_file_found)
+               file_one_included_p = 1;
 	      break;
 	    case DW_LNS_advance_line:
 	      line += read_signed_leb128 (abfd, line_ptr, &bytes_read);
 	      line_ptr += bytes_read;
+             if (!first_set_file_found)
+               file_one_included_p = 1;
 	      break;
 	    case DW_LNS_set_file:
               {
@@ -6055,11 +6077,14 @@ dwarf_decode_lines (struct line_header *
                   dir = comp_dir;
                 if (!decode_for_pst_p)
                   dwarf2_start_subfile (fe->name, dir);
+                first_set_file_found = 1;
               }
 	      break;
 	    case DW_LNS_set_column:
 	      column = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
 	      line_ptr += bytes_read;
+             if (!first_set_file_found)
+               file_one_included_p = 1;
 	      break;
 	    case DW_LNS_negate_stmt:
 	      is_stmt = (!is_stmt);
@@ -6075,10 +6100,14 @@ dwarf_decode_lines (struct line_header *
 	    case DW_LNS_const_add_pc:
 	      address += (lh->minimum_instruction_length
 			  * ((255 - lh->opcode_base) / lh->line_range));
+             if (!first_set_file_found)
+               file_one_included_p = 1;
 	      break;
 	    case DW_LNS_fixed_advance_pc:
 	      address += read_2_bytes (abfd, line_ptr);
 	      line_ptr += 2;
+             if (!first_set_file_found)
+               file_one_included_p = 1;
 	      break;
 	    default:
 	      {  /* Unknown standard opcode, ignore it.  */
@@ -6097,6 +6126,9 @@ dwarf_decode_lines (struct line_header *
     {
       int file_index;
 
+      if (file_one_included_p)
+        lh->file_names[0].included_p = 1;
+
       /* Now that we're done scanning the Line Header Program, we can
          create the psymtab of each included file.  */
       for (file_index = 0; file_index < lh->num_file_names; file_index++)


More information about the Gdb-patches mailing list