do not allow size or nbytes to go negative.
[deliverable/binutils-gdb.git] / gas / dwarf2dbg.c
index 12e126215da2a4ede331e94726727f116acfcc12..6e622067031f072704a128a8ba94dafbfa8f147f 100644 (file)
@@ -131,11 +131,6 @@ static struct file_entry *files;
 static unsigned int files_in_use;
 static unsigned int files_allocated;
 
-/* Correlate file numbers as given by the user in .file/.loc directives
-   with the file numbers used in the output debug info.  */
-static unsigned int *user_filenum;
-static unsigned int user_filenum_allocated;
-
 /* True when we've seen a .loc directive recently.  Used to avoid
    doing work when there's nothing to do.  */
 static boolean loc_directive_seen;
@@ -235,11 +230,20 @@ dwarf2_gen_line_info (ofs, loc)
 {
   struct line_subseg *ss;
   struct line_entry *e;
+  static unsigned int line = -1;
+  static unsigned int filenum = -1;
 
   /* Early out for as-yet incomplete location information.  */
   if (loc->filenum == 0 || loc->line == 0)
     return;
 
+  /* Don't emit sequences of line symbols for the same line. */
+  if (line == loc->line && filenum == loc->filenum)
+    return;
+
+  line = loc->line;
+  filenum = loc->filenum;
+
   e = (struct line_entry *) xmalloc (sizeof (*e));
   e->next = NULL;
   e->frag = frag_now;
@@ -305,9 +309,13 @@ get_filenum (filename)
 
   if (i >= files_allocated)
     {
+      unsigned int old = files_allocated;
+
       files_allocated = i + 32;
       files = (struct file_entry *)
        xrealloc (files, (i + 32) * sizeof (struct file_entry));
+
+      memset (files + old, 0, (i + 32 - old) * sizeof (struct file_entry));
     }
 
   files[i].filename = xstrdup (filename);
@@ -325,7 +333,7 @@ dwarf2_directive_file (dummy)
      int dummy ATTRIBUTE_UNUSED;
 {
   offsetT num;
-  const char *filename;
+  char *filename;
   int filename_len;
 
   /* Continue to accept a bare string and pass it off.  */
@@ -340,25 +348,33 @@ dwarf2_directive_file (dummy)
   filename = demand_copy_C_string (&filename_len);
   demand_empty_rest_of_line ();
 
-  if (num < 0)
+  if (num < 1)
+    {
+      as_bad (_("file number less than one"));
+      return;
+    }
+
+  if (num < (int) files_in_use && files[num].filename != 0)
     {
-      as_bad (_("File number less than zero"));
+      as_bad (_("file number %ld already allocated"), (long) num);
       return;
     }
 
-  if (num >= (int) user_filenum_allocated)
+  if (num >= (int) files_allocated)
     {
-      unsigned int old = user_filenum_allocated;
+      unsigned int old = files_allocated;
 
-      user_filenum_allocated = num + 16;
-      user_filenum = (unsigned int *)
-       xrealloc (user_filenum, (num + 16) * sizeof (unsigned int));
+      files_allocated = num + 16;
+      files = (struct file_entry *)
+       xrealloc (files, (num + 16) * sizeof (struct file_entry));
 
       /* Zero the new memory.  */
-      memset (user_filenum + old, 0, (num + 16 - old) * sizeof (unsigned int));
+      memset (files + old, 0, (num + 16 - old) * sizeof (struct file_entry));
     }
 
-  user_filenum[num] = get_filenum (filename);
+  files[num].filename = filename;
+  files[num].dir = 0;
+  files_in_use = num + 1;
 }
 
 void
@@ -374,19 +390,18 @@ dwarf2_directive_loc (dummy)
   column = get_absolute_expression ();
   demand_empty_rest_of_line ();
 
-  if (filenum < 0)
+  if (filenum < 1)
     {
-      as_bad (_("File number less than zero"));
+      as_bad (_("file number less than one"));
       return;
     }
-  if (filenum >= (int) user_filenum_allocated
-      || user_filenum[filenum] == 0)
+  if (filenum >= (int) files_in_use || files[filenum].filename == 0)
     {
-      as_bad (_("Unassigned file number %ld"), (long) filenum);
+      as_bad (_("unassigned file number %ld"), (long) filenum);
       return;
     }
 
-  current.filenum = user_filenum[filenum];
+  current.filenum = filenum;
   current.line = line;
   current.column = column;
   current.flags = DWARF2_FLAG_BEGIN_STMT;
@@ -518,8 +533,9 @@ get_frag_fix (frag)
   for (fr = frchain_root; fr; fr = fr->frch_next)
     if (fr->frch_last == frag)
       {
-       return ((char *) obstack_next_free (&fr->frch_obstack)
-               - frag->fr_literal);
+       long align_mask = -1 << get_recorded_alignment (fr->frch_seg);
+       return (((char *) obstack_next_free (&fr->frch_obstack)
+                - frag->fr_literal) + ~align_mask) & align_mask;
       }
 
   abort ();
@@ -766,7 +782,7 @@ dwarf2dbg_estimate_size_before_relax (frag)
   offsetT addr_delta;
   int size;
 
-  addr_delta = resolve_symbol_value (frag->fr_symbol, 0);
+  addr_delta = resolve_symbol_value (frag->fr_symbol);
   size = size_inc_line_addr (frag->fr_offset, addr_delta);
 
   frag->fr_subtype = size;
@@ -800,7 +816,7 @@ dwarf2dbg_convert_frag (frag)
 {
   offsetT addr_diff;
 
-  addr_diff = resolve_symbol_value (frag->fr_symbol, 1);
+  addr_diff = resolve_symbol_value (frag->fr_symbol);
 
   /* fr_var carries the max_chars that we created the fragment with.
      fr_subtype carries the current expected length.  We must, of
@@ -867,7 +883,11 @@ process_entries (seg, e)
          changed = 1;
        }
 
-      if (line != e->loc.line || changed)
+      /* Don't try to optimize away redundant entries; gdb wants two
+        entries for a function where the code starts on the same line as
+        the {, and there's no way to identify that case here.  Trust gcc
+        to optimize appropriately.  */
+      if (1 /* line != e->loc.line || changed */)
        {
          int line_delta = e->loc.line - line;
          if (frag == NULL)
@@ -921,6 +941,12 @@ out_file_list ()
 
   for (i = 1; i < files_in_use; ++i)
     {
+      if (files[i].filename == NULL)
+       {
+         as_bad (_("unassigned file number %ld"), (long) i);
+         continue;
+       }
+
       size = strlen (files[i].filename) + 1;
       cp = frag_more (size);
       memcpy (cp, files[i].filename, size);
@@ -1196,7 +1222,7 @@ dwarf2_finish ()
   struct line_seg *s;
 
   /* If no debug information was recorded, nothing to do.  */
-  if (all_segs == NULL)
+  if (all_segs == NULL && files_in_use <= 1)
     return;
 
   /* Calculate the size of an address for the target machine.  */
@@ -1223,7 +1249,7 @@ dwarf2_finish ()
 
   /* If this is assembler generated line info, we need .debug_info
      and .debug_abbrev sections as well.  */
-  if (debug_type == DEBUG_DWARF2)
+  if (all_segs != NULL && debug_type == DEBUG_DWARF2)
     {
       segT abbrev_seg;
       segT info_seg;
This page took 0.027402 seconds and 4 git commands to generate.