This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils 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: [patch] gas dwarf2 debug emission


Alan Modra wrote:
On Sat, Jan 22, 2005 at 05:42:08PM +0000, Nathan Sidwell wrote:

o  You're using the function to test whether a section is non-empty,
   but the code only looks at the first sub-section.  The function ought
   to run down frch_next, and be called seg_empty_p (or section_empty_p,
   gas nomenclature is a little confusing).

o  The function doesn't handle a number of frag types that might have
   fr_fix zero but still contribute to section size.  Correcting this
   isn't easy, and unfortunately I think it will be possible to
   construct cases where it's impossible to guess the frag size at this
   stage of assembly.  So I'll let this pass if you add a comment.

Like this? I chose 'seg_not_empty_p' to emphasize that a false result might not indicate actual emptiness.

built & tested on i686-pc-linux-gnu.

nathan

--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2005-01-23  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.

Index: gas/as.h
===================================================================
RCS file: /cvs/src/src/gas/as.h,v
retrieving revision 1.40
diff -c -3 -p -r1.40 as.h
*** gas/as.h	21 Jan 2005 05:54:38 -0000	1.40
--- gas/as.h	24 Jan 2005 16:54:32 -0000
*************** void   input_scrub_close (void);
*** 572,589 ****
  void   input_scrub_end (void);
  int    new_logical_line (char *, int);
  void   subsegs_begin (void);
- void   subseg_change (segT, int);
  segT   subseg_new (const char *, subsegT);
  segT   subseg_force_new (const char *, subsegT);
  void   subseg_set (segT, subsegT);
  int    subseg_text_p (segT);
  void   start_dependencies (char *);
  void   register_dependency (char *);
  void   print_dependencies (void);
  #ifdef BFD_ASSEMBLER
  segT   subseg_get (const char *, int);
  #endif
! 
  
  struct expressionS;
  struct fix;
--- 572,589 ----
  void   input_scrub_end (void);
  int    new_logical_line (char *, int);
  void   subsegs_begin (void);
  segT   subseg_new (const char *, subsegT);
  segT   subseg_force_new (const char *, subsegT);
  void   subseg_set (segT, subsegT);
  int    subseg_text_p (segT);
+ int    seg_not_empty_p (segT);
  void   start_dependencies (char *);
  void   register_dependency (char *);
  void   print_dependencies (void);
  #ifdef BFD_ASSEMBLER
  segT   subseg_get (const char *, int);
  #endif
! void   seg_change (segT, int);
  
  struct expressionS;
  struct fix;
Index: gas/dwarf2dbg.c
===================================================================
RCS file: /cvs/src/src/gas/dwarf2dbg.c,v
retrieving revision 1.72
diff -c -3 -p -r1.72 dwarf2dbg.c
*** gas/dwarf2dbg.c	22 Nov 2004 16:29:33 -0000	1.72
--- gas/dwarf2dbg.c	24 Jan 2005 16:54:33 -0000
*************** out_debug_info (segT info_seg, segT abbr
*** 1349,1369 ****
    symbol_set_value_now (info_end);
  }
  
  void
  dwarf2_finish (void)
  {
    segT line_seg;
    struct line_seg *s;
  
!   /* 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))
      return;
  
    /* Calculate the size of an address for the target machine.  */
--- 1349,1376 ----
    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) == 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.  */
*************** dwarf2_finish (void)
*** 1388,1401 ****
  
    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)
      {
        segT abbrev_seg;
-       segT info_seg;
        segT aranges_seg;
  
        info_seg = subseg_new (".debug_info", 0);
        abbrev_seg = subseg_new (".debug_abbrev", 0);
        aranges_seg = subseg_new (".debug_aranges", 0);
--- 1395,1410 ----
  
    out_debug_line (line_seg);
  
!   /* 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 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: gas/subsegs.c
===================================================================
RCS file: /cvs/src/src/gas/subsegs.c,v
retrieving revision 1.18
diff -c -3 -p -r1.18 subsegs.c
*** gas/subsegs.c	21 Jan 2005 05:54:38 -0000	1.18
--- gas/subsegs.c	24 Jan 2005 16:54:34 -0000
*************** subseg_text_p (segT sec)
*** 595,600 ****
--- 595,628 ----
  #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.  */
+ 
+ int
+ 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)
  {

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