This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA: separate line prologue reader from line statement reader



More prep for macro expansion.  I'll commit this in a few days if
nobody objects.

2002-02-12  Jim Blandy  <jimb@redhat.com>

	Separate the job of reading the line number info statement program
	prologue (...expialidocious) out into its own function.
	* dwarf2read.c (struct line_head, struct filenames, struct
	directories): Replace with...
	(struct line_prologue): New structure, containing the full
	contents of the statement program prologue, including the
	include directory and file name tables.
	(read_file_scope): If we have line number info, instead of just
	calling dwarf_decode_lines to do all the work, call
	dwarf_decode_line_prologue first to get a `struct line_prologue'
	containing the data in the statement program prologue, and then
	pass that to dwarf_decode_lines, which will pick up where that
	left off.  Be sure to clean up the `struct line_prologue' object.
	(dwarf_decode_line_prologue, free_line_prologue, add_include_dir,
	add_file_name): New functions.
	(dwarf_decode_lines): Move all the code to read the statement
	program prologue into dwarf_decode_line_prologue.  Take the line
	prologue it built as the first argument, instead of the offset to
	the compilation unit's line number info.  Use the new `struct
	line_prologue' type instead of the old structures.  No need to do
	cleanups here now, since we don't allocate anything.
	(dwarf2_statement_list_fits_in_line_number_section,
	dwarf2_line_prologue_too_long): New complaints.

Index: gdb/dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.51
diff -c -r1.51 dwarf2read.c
*** gdb/dwarf2read.c	2002/03/21 00:53:44	1.51
--- gdb/dwarf2read.c	2002/04/03 23:52:50
***************
*** 175,193 ****
                                           4 or 12 */
    };
  
! /* The data in the .debug_line statement prologue looks like this.  */
! struct line_head
    {
!     unsigned int total_length;
!     unsigned short version;
!     unsigned int prologue_length;
!     unsigned char minimum_instruction_length;
!     unsigned char default_is_stmt;
!     int line_base;
!     unsigned char line_range;
!     unsigned char opcode_base;
!     unsigned char *standard_opcode_lengths;
!   };
  
  /* When we construct a partial symbol table entry we only
     need this much information. */
--- 175,223 ----
                                           4 or 12 */
    };
  
! /* The line number information for a compilation unit (found in the
!    .debug_line section) begins with a "statement program prologue",
!    which contains the following information.  */
! struct line_prologue
! {
!   unsigned int total_length;
!   unsigned short version;
!   unsigned int prologue_length;
!   unsigned char minimum_instruction_length;
!   unsigned char default_is_stmt;
!   int line_base;
!   unsigned char line_range;
!   unsigned char opcode_base;
! 
!   /* standard_opcode_lengths[i] is the number of operands for the
!      standard opcode whose value is i.  This means that
!      standard_opcode_lengths[0] is unused, and the last meaningful
!      element is standard_opcode_lengths[opcode_base - 1].  */
!   unsigned char *standard_opcode_lengths;
! 
!   /* The include_directories table.  NOTE!  These strings are not
!      allocated with xmalloc; instead, they are pointers into
!      debug_line_buffer.  If you try to free them, `free' will get
!      indigestion.  */
!   unsigned int num_include_dirs, include_dirs_size;
!   char **include_dirs;
! 
!   /* The file_names table.  NOTE!  These strings are not allocated
!      with xmalloc; instead, they are pointers into debug_line_buffer.
!      Don't try to free them directly.  */
!   unsigned int num_file_names, file_names_size;
!   struct file_entry
    {
!     char *name;
!     unsigned int dir_index;
!     unsigned int mod_time;
!     unsigned int length;
!   } *file_names;
! 
!   /* The start and end of the statement program following this
!      prologue.  These point into dwarf_line_buffer.  */
!   char *statement_program_start, *statement_program_end;
! };
  
  /* When we construct a partial symbol table entry we only
     need this much information. */
***************
*** 492,497 ****
--- 522,531 ----
  {
    "missing .debug_line section", 0, 0
  };
+ static struct complaint dwarf2_statement_list_fits_in_line_number_section =
+ {
+   "statement list doesn't fit in .debug_line section", 0, 0
+ };
  static struct complaint dwarf2_mangled_line_number_section =
  {
    "mangled .debug_line section", 0, 0
***************
*** 560,565 ****
--- 594,603 ----
  {
    "unsupported const value attribute form: '%s'", 0, 0
  };
+ static struct complaint dwarf2_line_prologue_too_long =
+ {
+   "line number info prologue doesn't fit in `.debug_line' section", 0, 0
+ };
  
  /* local function prototypes */
  
***************
*** 638,645 ****
  static struct attribute *dwarf_attr (struct die_info *, unsigned int);
  
  static int die_is_declaration (struct die_info *);
  
! static void dwarf_decode_lines (unsigned int, char *, bfd *,
  				const struct comp_unit_head *);
  
  static void dwarf2_start_subfile (char *, char *);
--- 676,690 ----
  static struct attribute *dwarf_attr (struct die_info *, unsigned int);
  
  static int die_is_declaration (struct die_info *);
+ 
+ static void free_line_prologue (struct line_prologue *lp);
  
! static struct line_prologue *(dwarf_decode_line_prologue
!                               (unsigned int offset,
!                                bfd *abfd,
!                                const struct comp_unit_head *cu_header));
! 
! static void dwarf_decode_lines (struct line_prologue *, char *, bfd *,
  				const struct comp_unit_head *);
  
  static void dwarf2_start_subfile (char *, char *);
***************
*** 1545,1551 ****
  read_file_scope (struct die_info *die, struct objfile *objfile,
  		 const struct comp_unit_head *cu_header)
  {
!   unsigned int line_offset = 0;
    CORE_ADDR lowpc = ((CORE_ADDR) -1);
    CORE_ADDR highpc = ((CORE_ADDR) 0);
    struct attribute *attr;
--- 1590,1596 ----
  read_file_scope (struct die_info *die, struct objfile *objfile,
  		 const struct comp_unit_head *cu_header)
  {
!   struct cleanup *back_to = make_cleanup (null_cleanup, 0);
    CORE_ADDR lowpc = ((CORE_ADDR) -1);
    CORE_ADDR highpc = ((CORE_ADDR) 0);
    struct attribute *attr;
***************
*** 1553,1558 ****
--- 1598,1604 ----
    char *comp_dir = NULL;
    struct die_info *child_die;
    bfd *abfd = objfile->obfd;
+   struct line_prologue *line_prologue = 0;
  
    if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
      {
***************
*** 1637,1644 ****
    attr = dwarf_attr (die, DW_AT_stmt_list);
    if (attr)
      {
!       line_offset = DW_UNSND (attr);
!       dwarf_decode_lines (line_offset, comp_dir, abfd, cu_header);
      }
  
    /* Process all dies in compilation unit.  */
--- 1683,1697 ----
    attr = dwarf_attr (die, DW_AT_stmt_list);
    if (attr)
      {
!       unsigned int line_offset = DW_UNSND (attr);
!       line_prologue = dwarf_decode_line_prologue (line_offset,
!                                                   abfd, cu_header);
!       if (line_prologue)
!         {
!           make_cleanup ((make_cleanup_ftype *) free_line_prologue,
!                         (void *) line_prologue);
!           dwarf_decode_lines (line_prologue, comp_dir, abfd, cu_header);
!         }
      }
  
    /* Process all dies in compilation unit.  */
***************
*** 1651,1656 ****
--- 1704,1711 ----
  	  child_die = sibling_die (child_die);
  	}
      }
+ 
+   do_cleanups (back_to);
  }
  
  static void
***************
*** 3885,3971 ****
  	  && ! dwarf_attr (die, DW_AT_specification));
  }
  
! /* Decode the line number information for the compilation unit whose
!    line number info is at OFFSET in the .debug_line section.
!    The compilation directory of the file is passed in COMP_DIR.  */
  
! struct filenames
  {
!   unsigned int num_files;
!   struct fileinfo
      {
!       char *name;
!       unsigned int dir;
!       unsigned int time;
!       unsigned int size;
      }
!    *files;
! };
  
! struct directories
!   {
!     unsigned int num_dirs;
!     char **dirs;
!   };
  
  static void
! dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
! 		    const struct comp_unit_head *cu_header)
  {
-   char *line_ptr;
-   char *line_end;
-   struct line_head lh;
    struct cleanup *back_to;
!   unsigned int i, bytes_read;
!   char *cur_file, *cur_dir;
!   unsigned char op_code, extended_op, adj_opcode;
! 
! #define FILE_ALLOC_CHUNK 5
! #define DIR_ALLOC_CHUNK 5
! 
!   struct filenames files;
!   struct directories dirs;
  
    if (dwarf_line_buffer == NULL)
      {
        complain (&dwarf2_missing_line_number_section);
!       return;
      }
  
!   files.num_files = 0;
!   files.files = NULL;
  
!   dirs.num_dirs = 0;
!   dirs.dirs = NULL;
  
    line_ptr = dwarf_line_buffer + offset;
  
    /* read in the prologue */
!   lh.total_length = read_initial_length (abfd, line_ptr, NULL, &bytes_read);
    line_ptr += bytes_read;
!   line_end = line_ptr + lh.total_length;
!   lh.version = read_2_bytes (abfd, line_ptr);
    line_ptr += 2;
!   lh.prologue_length = read_offset (abfd, line_ptr, cu_header, &bytes_read);
    line_ptr += bytes_read;
!   lh.minimum_instruction_length = read_1_byte (abfd, line_ptr);
    line_ptr += 1;
!   lh.default_is_stmt = read_1_byte (abfd, line_ptr);
    line_ptr += 1;
!   lh.line_base = read_1_signed_byte (abfd, line_ptr);
    line_ptr += 1;
!   lh.line_range = read_1_byte (abfd, line_ptr);
    line_ptr += 1;
!   lh.opcode_base = read_1_byte (abfd, line_ptr);
    line_ptr += 1;
!   lh.standard_opcode_lengths = (unsigned char *)
!     xmalloc (lh.opcode_base * sizeof (unsigned char));
!   back_to = make_cleanup (free_current_contents, &lh.standard_opcode_lengths);
  
!   lh.standard_opcode_lengths[0] = 1;
!   for (i = 1; i < lh.opcode_base; ++i)
      {
!       lh.standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
        line_ptr += 1;
      }
  
--- 3940,4092 ----
  	  && ! dwarf_attr (die, DW_AT_specification));
  }
  
! 
! /* Free the line_prologue structure *LP, and any arrays and strings it
!    refers to.  */
! static void
! free_line_prologue (struct line_prologue *lp)
! {
!   if (lp->standard_opcode_lengths)
!     free (lp->standard_opcode_lengths);
! 
!   /* Remember that all the lp->file_names[i].name pointers are
!      pointers into debug_line_buffer, and don't need to be freed.  */
!   if (lp->file_names)
!     free (lp->file_names);
  
!   /* Similarly for the include directory names.  */
!   if (lp->include_dirs)
!     free (lp->include_dirs);
! 
!   free (lp);
! }
! 
! 
! /* Add an entry to LP's include directory table.  */
! static void
! add_include_dir (struct line_prologue *lp, char *include_dir)
  {
!   /* Grow the array if necessary.  */
!   if (lp->include_dirs_size == 0)
      {
!       lp->include_dirs_size = 1; /* for testing */
!       lp->include_dirs = xmalloc (lp->include_dirs_size
!                                   * sizeof (*lp->include_dirs));
      }
!   else if (lp->num_include_dirs >= lp->include_dirs_size)
!     {
!       lp->include_dirs_size *= 2;
!       lp->include_dirs = xrealloc (lp->include_dirs,
!                                    (lp->include_dirs_size
!                                     * sizeof (*lp->include_dirs)));
!     }
  
!   lp->include_dirs[lp->num_include_dirs++] = include_dir;
! }
!  
  
+ /* Add an entry to LP's file name table.  */
  static void
! add_file_name (struct line_prologue *lp,
!                char *name,
!                unsigned int dir_index,
!                unsigned int mod_time,
!                unsigned int length)
! {
!   struct file_entry *fe;
! 
!   /* Grow the array if necessary.  */
!   if (lp->file_names_size == 0)
!     {
!       lp->file_names_size = 1; /* for testing */
!       lp->file_names = xmalloc (lp->file_names_size
!                                 * sizeof (*lp->file_names));
!     }
!   else if (lp->num_file_names >= lp->file_names_size)
!     {
!       lp->file_names_size *= 2;
!       lp->file_names = xrealloc (lp->file_names,
!                                  (lp->file_names_size
!                                   * sizeof (*lp->file_names)));
!     }
! 
!   fe = &lp->file_names[lp->num_file_names++];
!   fe->name = name;
!   fe->dir_index = dir_index;
!   fe->mod_time = mod_time;
!   fe->length = length;
! }
!  
! 
! /* Read the statement program prologue starting at OFFSET in
!    dwarf_line_buffer, according to the endianness of ABFD.  Return a
!    pointer to a struct line_prologue, allocated using xmalloc.
! 
!    NOTE: the strings in the include directory and file name tables of
!    the returned object point into debug_line_buffer, and must not be
!    freed.  */
! static struct line_prologue *
! dwarf_decode_line_prologue (unsigned int offset, bfd *abfd,
!                             const struct comp_unit_head *cu_header)
  {
    struct cleanup *back_to;
!   struct line_prologue *lp;
!   char *line_ptr;
!   int bytes_read;
!   int i;
!   char *cur_dir, *cur_file;
  
    if (dwarf_line_buffer == NULL)
      {
        complain (&dwarf2_missing_line_number_section);
!       return 0;
      }
  
!   /* Make sure that at least there's room for the total_length field.  That
!      could be 12 bytes long, but we're just going to fudge that.  */
!   if (offset + 4 >= dwarf_line_size)
!     {
!       complain (&dwarf2_statement_list_fits_in_line_number_section);
!       return 0;
!     }
  
!   lp = xmalloc (sizeof (*lp));
!   memset (lp, 0, sizeof (*lp));
!   back_to = make_cleanup ((make_cleanup_ftype *) free_line_prologue,
!                           (void *) lp);
  
    line_ptr = dwarf_line_buffer + offset;
  
    /* read in the prologue */
!   lp->total_length = read_initial_length (abfd, line_ptr, NULL, &bytes_read);
    line_ptr += bytes_read;
!   if (line_ptr + lp->total_length > dwarf_line_buffer + dwarf_line_size)
!     {
!       complain (&dwarf2_statement_list_fits_in_line_number_section);
!       return 0;
!     }
!   lp->statement_program_end = line_ptr + lp->total_length;
!   lp->version = read_2_bytes (abfd, line_ptr);
    line_ptr += 2;
!   lp->prologue_length = read_offset (abfd, line_ptr, cu_header, &bytes_read);
    line_ptr += bytes_read;
!   lp->minimum_instruction_length = read_1_byte (abfd, line_ptr);
    line_ptr += 1;
!   lp->default_is_stmt = read_1_byte (abfd, line_ptr);
    line_ptr += 1;
!   lp->line_base = read_1_signed_byte (abfd, line_ptr);
    line_ptr += 1;
!   lp->line_range = read_1_byte (abfd, line_ptr);
    line_ptr += 1;
!   lp->opcode_base = read_1_byte (abfd, line_ptr);
    line_ptr += 1;
!   lp->standard_opcode_lengths
!     = (unsigned char *) xmalloc (lp->opcode_base * sizeof (unsigned char));
  
!   lp->standard_opcode_lengths[0] = 1;  /* This should never be used anyway.  */
!   for (i = 1; i < lp->opcode_base; ++i)
      {
!       lp->standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
        line_ptr += 1;
      }
  
***************
*** 3973,4017 ****
    while ((cur_dir = read_string (abfd, line_ptr, &bytes_read)) != NULL)
      {
        line_ptr += bytes_read;
!       if ((dirs.num_dirs % DIR_ALLOC_CHUNK) == 0)
! 	{
! 	  dirs.dirs = (char **)
! 	    xrealloc (dirs.dirs,
! 		      (dirs.num_dirs + DIR_ALLOC_CHUNK) * sizeof (char *));
! 	  if (dirs.num_dirs == 0)
! 	    make_cleanup (free_current_contents, &dirs.dirs);
! 	}
!       dirs.dirs[dirs.num_dirs++] = cur_dir;
      }
    line_ptr += bytes_read;
  
    /* Read file name table */
    while ((cur_file = read_string (abfd, line_ptr, &bytes_read)) != NULL)
      {
        line_ptr += bytes_read;
!       if ((files.num_files % FILE_ALLOC_CHUNK) == 0)
! 	{
! 	  files.files = (struct fileinfo *)
! 	    xrealloc (files.files,
! 		      (files.num_files + FILE_ALLOC_CHUNK)
! 		      * sizeof (struct fileinfo));
! 	  if (files.num_files == 0)
! 	    make_cleanup (free_current_contents, &files.files);
! 	}
!       files.files[files.num_files].name = cur_file;
!       files.files[files.num_files].dir =
! 	read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
        line_ptr += bytes_read;
!       files.files[files.num_files].time =
! 	read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
        line_ptr += bytes_read;
!       files.files[files.num_files].size =
! 	read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
        line_ptr += bytes_read;
!       files.num_files++;
      }
    line_ptr += bytes_read;
  
    /* Read the statement sequences until there's nothing left.  */
    while (line_ptr < line_end)
      {
--- 4094,4146 ----
    while ((cur_dir = read_string (abfd, line_ptr, &bytes_read)) != NULL)
      {
        line_ptr += bytes_read;
!       add_include_dir (lp, cur_dir);
      }
    line_ptr += bytes_read;
  
    /* Read file name table */
    while ((cur_file = read_string (abfd, line_ptr, &bytes_read)) != NULL)
      {
+       unsigned int dir_index, mod_time, length;
+ 
        line_ptr += bytes_read;
!       dir_index = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
        line_ptr += bytes_read;
!       mod_time = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
        line_ptr += bytes_read;
!       length = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
        line_ptr += bytes_read;
! 
!       add_file_name (lp, cur_file, dir_index, mod_time, length);
      }
    line_ptr += bytes_read;
+   lp->statement_program_start = line_ptr; 
+ 
+   if (line_ptr > dwarf_line_buffer + dwarf_line_size)
+     complain (&dwarf2_line_prologue_too_long);
+ 
+   discard_cleanups (back_to);
+   return lp;
+ }
+ 
+ 
+ /* Decode the line number information for the compilation unit whose
+    line number info is at OFFSET in the .debug_line section.
+    The compilation directory of the file is passed in COMP_DIR.  */
+ 
+ static void
+ dwarf_decode_lines (struct line_prologue *lp, char *comp_dir, bfd *abfd,
+ 		    const struct comp_unit_head *cu_header)
+ {
+   char *line_ptr;
+   char *line_end;
+   unsigned int i, bytes_read;
+   char *cur_dir;
+   unsigned char op_code, extended_op, adj_opcode;
  
+   line_ptr = lp->statement_program_start;
+   line_end = lp->statement_program_end;
+ 
    /* Read the statement sequences until there's nothing left.  */
    while (line_ptr < line_end)
      {
***************
*** 4020,4038 ****
        unsigned int file = 1;
        unsigned int line = 1;
        unsigned int column = 0;
!       int is_stmt = lh.default_is_stmt;
        int basic_block = 0;
        int end_sequence = 0;
  
        /* Start a subfile for the current file of the state machine.  */
!       if (files.num_files >= file)
  	{
! 	  /* The file and directory tables are 0 based, the references
! 	     are 1 based.  */
! 	  dwarf2_start_subfile (files.files[file - 1].name,
! 				(files.files[file - 1].dir
! 				 ? dirs.dirs[files.files[file - 1].dir - 1]
! 				 : comp_dir));
  	}
  
        /* Decode the table. */
--- 4149,4171 ----
        unsigned int file = 1;
        unsigned int line = 1;
        unsigned int column = 0;
!       int is_stmt = lp->default_is_stmt;
        int basic_block = 0;
        int end_sequence = 0;
  
        /* Start a subfile for the current file of the state machine.  */
!       if (lp->num_file_names >= file)
  	{
! 	  /* lp->include_dirs and lp->file_names are 0-based, but the
! 	     directory and file name numbers in the statement program
! 	     are 1-based.  */
!           struct file_entry *fe = &lp->file_names[file - 1];
!           char *dir;
!           if (fe->dir_index)
!             dir = lp->include_dirs[fe->dir_index - 1];
!           else
!             dir = comp_dir;
! 	  dwarf2_start_subfile (fe->name, dir);
  	}
  
        /* Decode the table. */
***************
*** 4041,4052 ****
  	  op_code = read_1_byte (abfd, line_ptr);
  	  line_ptr += 1;
  
! 	  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;
--- 4174,4185 ----
  	  op_code = read_1_byte (abfd, line_ptr);
  	  line_ptr += 1;
  
! 	  if (op_code >= lp->opcode_base)
  	    {		/* Special operand.  */
! 	      adj_opcode = op_code - lp->opcode_base;
! 	      address += (adj_opcode / lp->line_range)
! 		* lp->minimum_instruction_length;
! 	      line += lp->line_base + (adj_opcode % lp->line_range);
  	      /* append row to matrix using current values */
  	      record_line (current_subfile, line, address);
  	      basic_block = 1;
***************
*** 4074,4105 ****
  		  address += baseaddr;
  		  break;
  		case DW_LNE_define_file:
! 		  cur_file = read_string (abfd, line_ptr, &bytes_read);
! 		  line_ptr += bytes_read;
! 		  if ((files.num_files % FILE_ALLOC_CHUNK) == 0)
! 		    {
! 		      files.files = (struct fileinfo *)
! 			xrealloc (files.files,
! 				  (files.num_files + FILE_ALLOC_CHUNK)
! 				  * sizeof (struct fileinfo));
! 		      if (files.num_files == 0)
! 			make_cleanup (free_current_contents, &files.files);
! 		    }
! 		  files.files[files.num_files].name = cur_file;
! 		  files.files[files.num_files].dir =
! 		    read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
! 		  line_ptr += bytes_read;
! 		  files.files[files.num_files].time =
! 		    read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
! 		  line_ptr += bytes_read;
! 		  files.files[files.num_files].size =
! 		    read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
! 		  line_ptr += bytes_read;
! 		  files.num_files++;
  		  break;
  		default:
  		  complain (&dwarf2_mangled_line_number_section);
! 		  goto done;
  		}
  	      break;
  	    case DW_LNS_copy:
--- 4207,4233 ----
  		  address += baseaddr;
  		  break;
  		case DW_LNE_define_file:
!                   {
!                     char *cur_file;
!                     unsigned int dir_index, mod_time, length;
!                     
!                     cur_file = read_string (abfd, line_ptr, &bytes_read);
!                     line_ptr += bytes_read;
!                     dir_index =
!                       read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
!                     line_ptr += bytes_read;
!                     mod_time =
!                       read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
!                     line_ptr += bytes_read;
!                     length =
!                       read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
!                     line_ptr += bytes_read;
!                     add_file_name (lp, cur_file, dir_index, mod_time, length);
!                   }
  		  break;
  		default:
  		  complain (&dwarf2_mangled_line_number_section);
! 		  return;
  		}
  	      break;
  	    case DW_LNS_copy:
***************
*** 4107,4113 ****
  	      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;
  	      break;
--- 4235,4241 ----
  	      basic_block = 0;
  	      break;
  	    case DW_LNS_advance_pc:
! 	      address += lp->minimum_instruction_length
  		* read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
  	      line_ptr += bytes_read;
  	      break;
***************
*** 4116,4130 ****
  	      line_ptr += bytes_read;
  	      break;
  	    case DW_LNS_set_file:
! 	      /* The file and directory tables are 0 based, the references
! 	         are 1 based.  */
! 	      file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
! 	      line_ptr += bytes_read;
! 	      dwarf2_start_subfile
! 		(files.files[file - 1].name,
! 		 (files.files[file - 1].dir
! 		  ? dirs.dirs[files.files[file - 1].dir - 1]
! 		  : comp_dir));
  	      break;
  	    case DW_LNS_set_column:
  	      column = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
--- 4244,4264 ----
  	      line_ptr += bytes_read;
  	      break;
  	    case DW_LNS_set_file:
!               {
!                 /* lp->include_dirs and lp->file_names are 0-based,
!                    but the directory and file name numbers in the
!                    statement program are 1-based.  */
!                 struct file_entry *fe;
!                 char *dir;
!                 file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
!                 line_ptr += bytes_read;
!                 fe = &lp->file_names[file - 1];
!                 if (fe->dir_index)
!                   dir = lp->include_dirs[fe->dir_index - 1];
!                 else
!                   dir = comp_dir;
!                 dwarf2_start_subfile (fe->name, dir);
!               }
  	      break;
  	    case DW_LNS_set_column:
  	      column = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
***************
*** 4142,4149 ****
  	       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));
  	      break;
  	    case DW_LNS_fixed_advance_pc:
  	      address += read_2_bytes (abfd, line_ptr);
--- 4276,4283 ----
  	       length since special opcode 255 would have scaled the
  	       the increment.  */
  	    case DW_LNS_const_add_pc:
! 	      address += (lp->minimum_instruction_length
! 			  * ((255 - lp->opcode_base) / lp->line_range));
  	      break;
  	    case DW_LNS_fixed_advance_pc:
  	      address += read_2_bytes (abfd, line_ptr);
***************
*** 4152,4158 ****
  	    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;
--- 4286,4292 ----
  	    default:
  	      {  /* Unknown standard opcode, ignore it.  */
  		int i;
! 		for (i = 0; i < lp->standard_opcode_lengths[op_code]; i++)
  		  {
  		    (void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
  		    line_ptr += bytes_read;
***************
*** 4161,4168 ****
  	    }
  	}
      }
- done:
-   do_cleanups (back_to);
  }
  
  /* Start a subfile for DWARF.  FILENAME is the name of the file and
--- 4295,4300 ----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]