This is the mail archive of the binutils@sourceware.org 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]

Generate DW_AT_ranges for non-contiguous code


Let's try this again...

This enclosed (fixed) patch adds support for DW_AT_ranges when assembly code is noncontiguous. See: http://sourceware.org/ml/gdb/2006-05/msg00015.html for a discussion of the problem this is addressing.

I believe Tensilica's copyright assignment is already on file.

One issue here is that this particular usage of DW_AT_ranges is dwarf 3,
and gas emits 2 for the dwarf version number. Don't know the right thing
to do there. Bumping the version number for this seems extreme.

Let me know any issues...

Sterling Augustine
Member of Technical Staff
Tensilica, Inc.

gas/

2006-07-31 Sterling Augustine <sterling@tensilica.com>

    * dwarf2dbg.c (out_debug_info): Add new parameter ranges_seg
    and emit DW_AT_ranges when code in compilation unit is not
    contiguous.
    (out_debug_abbrev): Emit DW_AT_ranges abbreviation if code in
    is not contiguous.
    (dwarf2_finish): Create and pass ranges_seg to out_debug_info.
    (out_debug_ranges): New function to emit .debug_ranges section
    when code is not contiguous.



--- binutils-060728/gas/dwarf2dbg.c	2006-06-07 04:27:57.000000000 -0700
+++ updated/gas/dwarf2dbg.c	2006-07-31 11:11:58.584415000 -0700
@@ -201,8 +201,9 @@ static void process_entries (segT, struc
 static void out_file_list (void);
 static void out_debug_line (segT);
 static void out_debug_aranges (segT, segT);
+static void out_debug_ranges (segT);
 static void out_debug_abbrev (segT);
-static void out_debug_info (segT, segT, segT);
+static void out_debug_info (segT, segT, segT, segT);
 
 #ifndef TC_DWARF2_EMIT_OFFSET
 # define TC_DWARF2_EMIT_OFFSET  generic_dwarf2_emit_offset
@@ -1293,6 +1294,54 @@ out_debug_line (segT line_seg)
 /* Emit data for .debug_aranges.  */
 
 static void
+out_debug_ranges (segT ranges_seg)
+{
+  unsigned int addr_size = sizeof_address;
+  struct line_seg *s;
+  expressionS expr;
+  unsigned int i;
+
+  subseg_set (ranges_seg, 0);
+
+  /* Base Address Entry.  */
+  for (i = 0; i < addr_size; i++) 
+      out_byte (0xff);
+  for (i = 0; i < addr_size; i++) 
+      out_byte (0);
+
+  /* Range List Entry.  */
+  for (s = all_segs; s; s = s->next)
+    {
+      fragS *frag;
+      symbolS *beg, *end;
+
+      frag = first_frag_for_seg (s->seg);
+      beg = symbol_temp_new (s->seg, 0, frag);
+      s->text_start = beg;
+
+      frag = last_frag_for_seg (s->seg);
+      end = symbol_temp_new (s->seg, get_frag_fix (frag, s->seg), frag);
+      s->text_end = end;
+
+      expr.X_op = O_symbol;
+      expr.X_add_symbol = beg;
+      expr.X_add_number = 0;
+      emit_expr (&expr, addr_size);
+
+      expr.X_op = O_symbol;
+      expr.X_add_symbol = end;
+      expr.X_add_number = 0;
+      emit_expr (&expr, addr_size);
+    }
+
+  /* End of Range Entry.   */
+  for (i = 0; i < addr_size; i++) 
+      out_byte (0);
+  for (i = 0; i < addr_size; i++) 
+      out_byte (0);
+}
+
+static void
 out_debug_aranges (segT aranges_seg, segT info_seg)
 {
   unsigned int addr_size = sizeof_address;
@@ -1382,6 +1431,13 @@ out_debug_abbrev (segT abbrev_seg)
       out_abbrev (DW_AT_low_pc, DW_FORM_addr);
       out_abbrev (DW_AT_high_pc, DW_FORM_addr);
     }
+  else
+    {
+      if (DWARF2_FORMAT () == dwarf2_format_32bit)
+	out_abbrev (DW_AT_ranges, DW_FORM_data4);
+      else
+	out_abbrev (DW_AT_ranges, DW_FORM_data8);
+    }
   out_abbrev (DW_AT_name, DW_FORM_string);
   out_abbrev (DW_AT_comp_dir, DW_FORM_string);
   out_abbrev (DW_AT_producer, DW_FORM_string);
@@ -1395,7 +1451,7 @@ out_debug_abbrev (segT abbrev_seg)
 /* Emit a description of this compilation unit for .debug_info.  */
 
 static void
-out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg)
+out_debug_info (segT info_seg, segT abbrev_seg, segT line_seg, segT ranges_seg)
 {
   char producer[128];
   char *comp_dir;
@@ -1458,8 +1514,7 @@ out_debug_info (segT info_seg, segT abbr
   /* ??? sizeof_offset */
   TC_DWARF2_EMIT_OFFSET (section_symbol (line_seg), 4);
 
-  /* These two attributes may only be emitted if all of the code is
-     contiguous.  Multiple sections are not that.  */
+  /* These two attributes are emitted if all of the code is contiguous.  */
   if (all_segs->next == NULL)
     {
       /* DW_AT_low_pc */
@@ -1474,6 +1529,16 @@ out_debug_info (segT info_seg, segT abbr
       expr.X_add_number = 0;
       emit_expr (&expr, sizeof_address);
     }
+  else
+    {
+      /* This attributes is emitted if the code is disjoint.  */
+      
+      /* DW_AT_ranges */
+      expr.X_op = O_symbol;
+      expr.X_add_symbol = section_symbol (ranges_seg);
+      expr.X_add_number = 0;
+      emit_expr (&expr, sizeof_address);
+    }
 
   /* DW_AT_name.  We don't have the actual file name that was present
      on the command line, so assume files[1] is the main input file.
@@ -1564,6 +1629,7 @@ dwarf2_finish (void)
     {
       segT abbrev_seg;
       segT aranges_seg;
+      segT ranges_seg;
 
       assert (all_segs);
       
@@ -1580,8 +1646,19 @@ dwarf2_finish (void)
 
       record_alignment (aranges_seg, ffs (2 * sizeof_address) - 1);
 
+      if (all_segs->next == NULL)
+	ranges_seg = NULL;
+      else
+	{
+	  ranges_seg = subseg_new (".debug_ranges", 0);
+	  bfd_set_section_flags (stdoutput, ranges_seg, 
+				 SEC_READONLY | SEC_DEBUGGING);
+	  record_alignment (ranges_seg, ffs (2 * sizeof_address) - 1);
+	  out_debug_ranges (ranges_seg);
+	}
+
       out_debug_aranges (aranges_seg, info_seg);
       out_debug_abbrev (abbrev_seg);
-      out_debug_info (info_seg, abbrev_seg, line_seg);
+      out_debug_info (info_seg, abbrev_seg, line_seg, ranges_seg);
     }
 }

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