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]

Re: DWARF updates for linker relaxation?


On Mon, 17 Jul 2006 at 14:32:46 -0700, Bob Wilson wrote:
> How do I make this work? It seems like the obvious approach is to have a hook
> in the assembler to make it use the generic "advance_pc" opcode instead of
> "special opcodes", with relocations on the address offset fields. The SH code
> mentioned above made me think there might already be code for this somewhere
> in the assembler, but I haven't found it.
>
> Any suggestions?

I didn't get any suggestions or pointers to existing code, so I came up with my own solution for this. It allows a port to specify that DWARF line numbers should be specified using the DW_LNS_fixed_advance_pc opcodes. This allows linker relaxation to update the PC offsets, at the expense of slightly larger .debug_line sections.

I tested this by building for both i686-pc-linux-gnu and xtensa-elf targets. The testsuite passes with no regressions, except for one. For the xtensa-elf target, the lns/lns-common-1 test fails because the expected dump file no longer matches. Is there an easy way to specify an alternate expected dump file? Otherwise, I guess I could skip this test for Xtensa targets.

Assuming I get that regression fixed, is this OK?

2006-07-28 Bob Wilson <bob.wilson@acm.org>

	* dwarf2dbg.c (DWARF2_USE_FIXED_ADVANCE_PC): New.
	(out_sleb128): New.
	(out_fixed_inc_line_addr): New.
	(process_entries): Use out_fixed_inc_line_addr when
	DWARF2_USE_FIXED_ADVANCE_PC is set.
	* config/tc-xtensa.h (DWARF2_USE_FIXED_ADVANCE_PC): Define.

Index: dwarf2dbg.c
===================================================================
RCS file: /cvs/src/src/gas/dwarf2dbg.c,v
retrieving revision 1.85
diff -u -p -r1.85 dwarf2dbg.c
--- dwarf2dbg.c	7 Jun 2006 11:27:57 -0000	1.85
+++ dwarf2dbg.c	28 Jul 2006 22:57:04 -0000
@@ -88,6 +88,13 @@
 #define DL_FILES	1
 #define DL_BODY		2
 
+/* If linker relaxation might change offsets in the code, the DWARF special
+   opcodes and variable-length operands cannot be used.  If this macro is
+   nonzero, use the DW_LNS_fixed_advance_pc opcode instead.  */
+#ifndef DWARF2_USE_FIXED_ADVANCE_PC
+# define DWARF2_USE_FIXED_ADVANCE_PC	0
+#endif
+
 /* First special line opcde - leave room for the standard opcodes.
    Note: If you want to change this, you'll have to update the
    "standard_opcode_lengths" table that is emitted below in
@@ -191,11 +198,13 @@ static void out_two (int);
 static void out_four (int);
 static void out_abbrev (int, int);
 static void out_uleb128 (addressT);
+static void out_sleb128 (addressT);
 static offsetT get_frag_fix (fragS *, segT);
 static void out_set_addr (symbolS *);
 static int size_inc_line_addr (int, addressT);
 static void emit_inc_line_addr (int, addressT, char *, int);
 static void out_inc_line_addr (int, addressT);
+static void out_fixed_inc_line_addr (int, symbolS *, symbolS *);
 static void relax_inc_line_addr (int, symbolS *, symbolS *);
 static void process_entries (segT, struct line_entry *);
 static void out_file_list (void);
@@ -746,6 +755,14 @@ out_uleb128 (addressT value)
   output_leb128 (frag_more (sizeof_leb128 (value, 0)), value, 0);
 }
 
+/* Emit a signed "little-endian base 128" number.  */
+
+static void
+out_sleb128 (addressT value)
+{
+  output_leb128 (frag_more (sizeof_leb128 (value, 1)), value, 1);
+}
+
 /* Emit a tuple for .debug_abbrev.  */
 
 static inline void
@@ -979,6 +996,45 @@ out_inc_line_addr (int line_delta, addre
   emit_inc_line_addr (line_delta, addr_delta, frag_more (len), len);
 }
 
+/* Write out an alternative form of line and address skips using
+   DW_LNS_fixed_advance_pc opcodes.  This uses more space than the default
+   line and address information, but it helps support linker relaxation that
+   changes the code offsets.  */
+
+static void
+out_fixed_inc_line_addr (int line_delta, symbolS *to_sym, symbolS *from_sym)
+{
+  expressionS expr;
+
+  /* INT_MAX is a signal that this is actually a DW_LNE_end_sequence.  */
+  if (line_delta == INT_MAX)
+    {
+      out_opcode (DW_LNS_fixed_advance_pc);
+      expr.X_op = O_subtract;
+      expr.X_add_symbol = to_sym;
+      expr.X_op_symbol = from_sym;
+      expr.X_add_number = 0;
+      emit_expr (&expr, 2);
+
+      out_opcode (DW_LNS_extended_op);
+      out_byte (1);
+      out_opcode (DW_LNE_end_sequence);
+      return;
+    }
+
+  out_opcode (DW_LNS_advance_line);
+  out_sleb128 (line_delta);
+
+  out_opcode (DW_LNS_fixed_advance_pc);
+  expr.X_op = O_subtract;
+  expr.X_add_symbol = to_sym;
+  expr.X_op_symbol = from_sym;
+  expr.X_add_number = 0;
+  emit_expr (&expr, 2);
+
+  out_opcode (DW_LNS_copy);
+}
+
 /* Generate a variant frag that we can use to relax address/line
    increments between fragments of the target segment.  */
 
@@ -1129,6 +1185,8 @@ process_entries (segT seg, struct line_e
 	  out_set_addr (lab);
 	  out_inc_line_addr (line_delta, 0);
 	}
+      else if (DWARF2_USE_FIXED_ADVANCE_PC)
+	out_fixed_inc_line_addr (line_delta, lab, last_lab);
       else if (frag == last_frag)
 	out_inc_line_addr (line_delta, frag_ofs - last_frag_ofs);
       else
@@ -1148,7 +1206,12 @@ process_entries (segT seg, struct line_e
   /* Emit a DW_LNE_end_sequence for the end of the section.  */
   frag = last_frag_for_seg (seg);
   frag_ofs = get_frag_fix (frag, seg);
-  if (frag == last_frag)
+  if (DWARF2_USE_FIXED_ADVANCE_PC)
+    {
+      lab = symbol_temp_new (seg, frag_ofs, frag);
+      out_fixed_inc_line_addr (INT_MAX, lab, last_lab);
+    }
+  else if (frag == last_frag)
     out_inc_line_addr (INT_MAX, frag_ofs - last_frag_ofs);
   else
     {
Index: config/tc-xtensa.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-xtensa.h,v
retrieving revision 1.19
diff -u -p -r1.19 tc-xtensa.h
--- config/tc-xtensa.h	31 Jan 2006 19:36:57 -0000	1.19
+++ config/tc-xtensa.h	28 Jul 2006 22:57:05 -0000
@@ -371,6 +371,9 @@ extern char *xtensa_section_rename (char
 #define MD_APPLY_SYM_VALUE(FIX) 0
 #define SUB_SEGMENT_ALIGN(SEG, FRCHAIN) 0
 
+/* Use line number format that is amenable to linker relaxation.  */
+#define DWARF2_USE_FIXED_ADVANCE_PC (linkrelax != 0)
+
 
 /* Resource reservation info functions.  */
 

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