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]

Re: RFA: separate line prologue reader from line statement reader



I've committed this patch, after changing some terminology to match
the newer Dwarf spec.  The revised patch is below.

Jim Blandy <jimb@redhat.com> writes:
> 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.


2002-05-06  Jim Blandy  <jimb@redhat.com>

	Separate the job of reading the line number info statement program
	header (...expialidocious) out into its own function.
	* dwarf2read.c (struct line_head, struct filenames, struct
	directories): Replace with...
	(struct line_header): New structure, containing the full
	contents of the statement program header, 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_header first to get a `struct line_header'
	containing the data in the statement program header, and then
	pass that to dwarf_decode_lines, which will pick up where that
	left off.  Be sure to clean up the `struct line_header' object.
	(dwarf_decode_line_header, free_line_header, add_include_dir,
	add_file_name): New functions.
	(dwarf_decode_lines): Move all the code to read the statement
	program header into dwarf_decode_line_header.  Take the line
	header it built as the first argument, instead of the offset to
	the compilation unit's line number info.  Use the new `struct
	line_header' 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_header_too_long): New complaints.

Index: gdb/dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.53
diff -c -r1.53 dwarf2read.c
*** gdb/dwarf2read.c	26 Apr 2002 20:08:19 -0000	1.53
--- gdb/dwarf2read.c	6 May 2002 20:52:32 -0000
***************
*** 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 header",
!    which contains the following information.  */
! struct line_header
! {
!   unsigned int total_length;
!   unsigned short version;
!   unsigned int header_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
!      header.  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. */
***************
*** 502,507 ****
--- 532,541 ----
  {
    "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
***************
*** 574,579 ****
--- 608,617 ----
  {
    "misplaced first line number at 0x%lx for '%s'", 0, 0
  };
+ static struct complaint dwarf2_line_header_too_long =
+ {
+   "line number info header doesn't fit in `.debug_line' section", 0, 0
+ };
  
  /* local function prototypes */
  
***************
*** 653,659 ****
  
  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 *);
--- 691,704 ----
  
  static int die_is_declaration (struct die_info *);
  
! static void free_line_header (struct line_header *lh);
! 
! static struct line_header *(dwarf_decode_line_header
!                             (unsigned int offset,
!                              bfd *abfd,
!                              const struct comp_unit_head *cu_header));
! 
! static void dwarf_decode_lines (struct line_header *, char *, bfd *,
  				const struct comp_unit_head *);
  
  static void dwarf2_start_subfile (char *, char *);
***************
*** 1569,1575 ****
  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;
--- 1614,1620 ----
  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;
***************
*** 1577,1582 ****
--- 1622,1628 ----
    char *comp_dir = NULL;
    struct die_info *child_die;
    bfd *abfd = objfile->obfd;
+   struct line_header *line_header = 0;
  
    if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
      {
***************
*** 1674,1682 ****
    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);
      }
  }
  
  static void
--- 1720,1737 ----
    attr = dwarf_attr (die, DW_AT_stmt_list);
    if (attr)
      {
!       unsigned int line_offset = DW_UNSND (attr);
!       line_header = dwarf_decode_line_header (line_offset,
!                                               abfd, cu_header);
!       if (line_header)
!         {
!           make_cleanup ((make_cleanup_ftype *) free_line_header,
!                         (void *) line_header);
!           dwarf_decode_lines (line_header, comp_dir, abfd, cu_header);
!         }
      }
+ 
+   do_cleanups (back_to);
  }
  
  static void
***************
*** 3945,3972 ****
  	  && ! 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;
!   };
  
  /* This function exists to work around a bug in certain compilers
     (particularly GCC 2.95), in which the first line number marker of a
--- 4000,4187 ----
  	  && ! dwarf_attr (die, DW_AT_specification));
  }
  
  
! /* Free the line_header structure *LH, and any arrays and strings it
!    refers to.  */
! static void
! free_line_header (struct line_header *lh)
  {
!   if (lh->standard_opcode_lengths)
!     free (lh->standard_opcode_lengths);
! 
!   /* Remember that all the lh->file_names[i].name pointers are
!      pointers into debug_line_buffer, and don't need to be freed.  */
!   if (lh->file_names)
!     free (lh->file_names);
! 
!   /* Similarly for the include directory names.  */
!   if (lh->include_dirs)
!     free (lh->include_dirs);
! 
!   free (lh);
! }
! 
! 
! /* Add an entry to LH's include directory table.  */
! static void
! add_include_dir (struct line_header *lh, char *include_dir)
! {
!   /* Grow the array if necessary.  */
!   if (lh->include_dirs_size == 0)
      {
!       lh->include_dirs_size = 1; /* for testing */
!       lh->include_dirs = xmalloc (lh->include_dirs_size
!                                   * sizeof (*lh->include_dirs));
!     }
!   else if (lh->num_include_dirs >= lh->include_dirs_size)
!     {
!       lh->include_dirs_size *= 2;
!       lh->include_dirs = xrealloc (lh->include_dirs,
!                                    (lh->include_dirs_size
!                                     * sizeof (*lh->include_dirs)));
      }
  
!   lh->include_dirs[lh->num_include_dirs++] = include_dir;
! }
!  
! 
! /* Add an entry to LH's file name table.  */
! static void
! add_file_name (struct line_header *lh,
!                char *name,
!                unsigned int dir_index,
!                unsigned int mod_time,
!                unsigned int length)
! {
!   struct file_entry *fe;
! 
!   /* Grow the array if necessary.  */
!   if (lh->file_names_size == 0)
!     {
!       lh->file_names_size = 1; /* for testing */
!       lh->file_names = xmalloc (lh->file_names_size
!                                 * sizeof (*lh->file_names));
!     }
!   else if (lh->num_file_names >= lh->file_names_size)
!     {
!       lh->file_names_size *= 2;
!       lh->file_names = xrealloc (lh->file_names,
!                                  (lh->file_names_size
!                                   * sizeof (*lh->file_names)));
!     }
! 
!   fe = &lh->file_names[lh->num_file_names++];
!   fe->name = name;
!   fe->dir_index = dir_index;
!   fe->mod_time = mod_time;
!   fe->length = length;
! }
!  
! 
! /* Read the statement program header starting at OFFSET in
!    dwarf_line_buffer, according to the endianness of ABFD.  Return a
!    pointer to a struct line_header, 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_header *
! dwarf_decode_line_header (unsigned int offset, bfd *abfd,
!                           const struct comp_unit_head *cu_header)
! {
!   struct cleanup *back_to;
!   struct line_header *lh;
!   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;
!     }
! 
!   lh = xmalloc (sizeof (*lh));
!   memset (lh, 0, sizeof (*lh));
!   back_to = make_cleanup ((make_cleanup_ftype *) free_line_header,
!                           (void *) lh);
! 
!   line_ptr = dwarf_line_buffer + offset;
! 
!   /* read in the header */
!   lh->total_length = read_initial_length (abfd, line_ptr, NULL, &bytes_read);
!   line_ptr += bytes_read;
!   if (line_ptr + lh->total_length > dwarf_line_buffer + dwarf_line_size)
!     {
!       complain (&dwarf2_statement_list_fits_in_line_number_section);
!       return 0;
!     }
!   lh->statement_program_end = line_ptr + lh->total_length;
!   lh->version = read_2_bytes (abfd, line_ptr);
!   line_ptr += 2;
!   lh->header_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));
! 
!   lh->standard_opcode_lengths[0] = 1;  /* This should never be used anyway.  */
!   for (i = 1; i < lh->opcode_base; ++i)
!     {
!       lh->standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
!       line_ptr += 1;
!     }
! 
!   /* Read directory table  */
!   while ((cur_dir = read_string (abfd, line_ptr, &bytes_read)) != NULL)
!     {
!       line_ptr += bytes_read;
!       add_include_dir (lh, 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 (lh, cur_file, dir_index, mod_time, length);
!     }
!   line_ptr += bytes_read;
!   lh->statement_program_start = line_ptr; 
! 
!   if (line_ptr > dwarf_line_buffer + dwarf_line_size)
!     complain (&dwarf2_line_header_too_long);
! 
!   discard_cleanups (back_to);
!   return lh;
! }
  
  /* This function exists to work around a bug in certain compilers
     (particularly GCC 2.95), in which the first line number marker of a
***************
*** 4013,4121 ****
    return fn->lowpc;
  }
  
  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;
!     }
! 
!   /* Read directory table  */
!   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)
--- 4228,4249 ----
    return fn->lowpc;
  }
  
+ /* 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_header *lh, 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 = lh->statement_program_start;
!   line_end = lh->statement_program_end;
  
    /* Read the statement sequences until there's nothing left.  */
    while (line_ptr < line_end)
***************
*** 4125,4143 ****
        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. */
--- 4253,4275 ----
        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 (lh->num_file_names >= file)
  	{
! 	  /* lh->include_dirs and lh->file_names are 0-based, but the
! 	     directory and file name numbers in the statement program
! 	     are 1-based.  */
!           struct file_entry *fe = &lh->file_names[file - 1];
!           char *dir;
!           if (fe->dir_index)
!             dir = lh->include_dirs[fe->dir_index - 1];
!           else
!             dir = comp_dir;
! 	  dwarf2_start_subfile (fe->name, dir);
  	}
  
        /* Decode the table. */
***************
*** 4146,4157 ****
  	  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 */
  	      address = check_cu_functions (address);
  	      record_line (current_subfile, line, address);
--- 4278,4289 ----
  	  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 */
  	      address = check_cu_functions (address);
  	      record_line (current_subfile, line, address);
***************
*** 4175,4206 ****
  		  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:
--- 4307,4333 ----
  		  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 (lh, cur_file, dir_index, mod_time, length);
!                   }
  		  break;
  		default:
  		  complain (&dwarf2_mangled_line_number_section);
! 		  return;
  		}
  	      break;
  	    case DW_LNS_copy:
***************
*** 4209,4215 ****
  	      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;
--- 4336,4342 ----
  	      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;
***************
*** 4218,4232 ****
  	      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);
--- 4345,4365 ----
  	      line_ptr += bytes_read;
  	      break;
  	    case DW_LNS_set_file:
!               {
!                 /* lh->include_dirs and lh->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 = &lh->file_names[file - 1];
!                 if (fe->dir_index)
!                   dir = lh->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);
***************
*** 4244,4251 ****
  	       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);
--- 4377,4384 ----
  	       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);
***************
*** 4254,4260 ****
  	    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;
--- 4387,4393 ----
  	    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;
***************
*** 4263,4270 ****
  	    }
  	}
      }
- done:
-   do_cleanups (back_to);
  }
  
  /* Start a subfile for DWARF.  FILENAME is the name of the file and
--- 4396,4401 ----


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