From c6cb92c5ba6f9001097e4ae97f265ba28ff0d975 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 27 Jan 2005 16:33:47 +0000 Subject: [PATCH] * 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. --- gas/ChangeLog | 7 +++++++ gas/as.h | 2 +- gas/dwarf2dbg.c | 35 ++++++++++++++++++++++------------- gas/subsegs.c | 28 ++++++++++++++++++++++++++++ 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 + + * 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 * 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) { -- 2.34.1