summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2005-01-27 16:33:47 +0000
committerNathan Sidwell <nathan@codesourcery.com>2005-01-27 16:33:47 +0000
commitc6cb92c5ba6f9001097e4ae97f265ba28ff0d975 (patch)
treeb6cc25af4f0f4f1c9246c7e359414a18198a793d
parente80937925fd99e09392fe3f76e4cce1b1b42105f (diff)
* 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.
-rw-r--r--gas/ChangeLog7
-rw-r--r--gas/as.h2
-rw-r--r--gas/dwarf2dbg.c35
-rw-r--r--gas/subsegs.c28
4 files changed, 58 insertions, 14 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index e41242e345..f635784290 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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.
diff --git a/gas/as.h b/gas/as.h
index 4d790bfb6b..9ffc99cda9 100644
--- 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;
diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c
index d3b5e85283..b452834889 100644
--- a/gas/dwarf2dbg.c
+++ b/gas/dwarf2dbg.c
@@ -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);
diff --git a/gas/subsegs.c b/gas/subsegs.c
index c63f3010ea..287dd1700c 100644
--- a/gas/subsegs.c
+++ b/gas/subsegs.c
@@ -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)
{