* dwarf2dbg.c (dwarf2_finish): Correct logic for determining when
authorNathan Sidwell <nathan@codesourcery.com>
Thu, 27 Jan 2005 16:33:47 +0000 (16:33 +0000)
committerNathan Sidwell <nathan@codesourcery.com>
Thu, 27 Jan 2005 16:33:47 +0000 (16:33 +0000)
to emit .debug_line and other debug sections.
* as.h (seg_not_empty_p): Declare.
* subsegs.c (seg_not_empty_p): New predicate.

gas/ChangeLog
gas/as.h
gas/dwarf2dbg.c
gas/subsegs.c

index e41242e..f635784 100644 (file)
@@ -1,3 +1,10 @@
+2005-01-27  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * dwarf2dbg.c (dwarf2_finish): Correct logic for determining when
+       to emit .debug_line and other debug sections.
+       * as.h (seg_not_empty_p): Declare.
+       * subsegs.c (seg_not_empty_p): New predicate.
+
 2005-01-27  Andrew Cagney  <cagney@gnu.org>
 
        * configure: Regenerate to track ../gettext.m4 change.
index 4d790bf..9ffc99c 100644 (file)
--- a/gas/as.h
+++ b/gas/as.h
@@ -577,6 +577,7 @@ segT   subseg_new (const char *, subsegT);
 segT   subseg_force_new (const char *, subsegT);
 void   subseg_set (segT, subsegT);
 int    subseg_text_p (segT);
+bfd_boolean seg_not_empty_p (segT);
 void   start_dependencies (char *);
 void   register_dependency (char *);
 void   print_dependencies (void);
@@ -584,7 +585,6 @@ void   print_dependencies (void);
 segT   subseg_get (const char *, int);
 #endif
 
-
 struct expressionS;
 struct fix;
 typedef struct symbol symbolS;
index d3b5e85..b452834 100644 (file)
@@ -1349,21 +1349,28 @@ out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg)
   symbol_set_value_now (info_end);
 }
 
+/* Finish the dwarf2 debug sections.  We emit .debug.line if there
+   were any .file/.loc directives, or --gdwarf2 was given, or if the
+   file has a non-empty .debug_info section.  If we emit .debug_line,
+   and the .debug_info section is empty, we also emit .debug_info,
+   .debug_aranges and .debug_abbrev.  ALL_SEGS will be non-null if
+   there were any .file/.loc directives, or --gdwarf2 was given and
+   there were any located instructions emitted.  */
+
 void
 dwarf2_finish (void)
 {
   segT line_seg;
   struct line_seg *s;
+  segT info_seg;
+  int emit_other_sections = 0;
+
+  info_seg = bfd_get_section_by_name (stdoutput, ".debug_info");
+  emit_other_sections = info_seg == NULL || !seg_not_empty_p (info_seg);
 
-  /* We don't need to do anything unless:
-     - Some debug information was recorded via .file/.loc or
-       generated by GAS (--gdwarf2)
-     - or, there is a user-provided .debug_info section which could
-       reference the file table in the .debug_line section we generate
-       below.  */
-  if (all_segs == NULL
-      && (bfd_get_section_by_name (stdoutput, ".debug_info") == NULL
-         || files_in_use == 0))
+  if (!all_segs && emit_other_sections)
+    /* There is no line information and no non-empty .debug_info
+       section.  */
     return;
 
   /* Calculate the size of an address for the target machine.  */
@@ -1388,14 +1395,16 @@ dwarf2_finish (void)
 
   out_debug_line (line_seg);
 
-  /* If this is assembler generated line info, we need .debug_info
-     and .debug_abbrev sections as well.  */
-  if (all_segs != NULL && debug_type == DEBUG_DWARF2)
+  /* If this is assembler generated line info, and there is no
+     debug_info already, we need .debug_info and .debug_abbrev
+     sections as well.  */
+  if (emit_other_sections)
     {
       segT abbrev_seg;
-      segT info_seg;
       segT aranges_seg;
 
+      assert (all_segs);
+      
       info_seg = subseg_new (".debug_info", 0);
       abbrev_seg = subseg_new (".debug_abbrev", 0);
       aranges_seg = subseg_new (".debug_aranges", 0);
index c63f301..287dd17 100644 (file)
@@ -595,6 +595,34 @@ subseg_text_p (segT sec)
 #endif /* ! BFD_ASSEMBLER */
 }
 
+/* Return non zero if SEC has at least one byte of data.  It is
+   possible that we'll return zero even on a non-empty section because
+   we don't know all the fragment types, and it is possible that an
+   fr_fix == 0 one still contributes data.  Think of this as
+   seg_definitely_not_empty_p.  */
+
+bfd_boolean
+seg_not_empty_p (segT sec)
+{
+  segment_info_type *seginfo = seg_info (sec);
+  frchainS *chain;
+  fragS *frag;
+
+  if (!seginfo)
+    return 0;
+  
+  for (chain = seginfo->frchainP; chain; chain = chain->frch_next)
+    {
+      for (frag = chain->frch_root; frag; frag = frag->fr_next)
+       if (frag->fr_fix)
+         return 1;
+      if (obstack_next_free (&chain->frch_obstack)
+         != chain->frch_last->fr_literal)
+       return 1;
+    }
+  return 0;
+}
+
 void
 subsegs_print_statistics (FILE *file)
 {