public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Bob Wilson <bwilson@tensilica.com>
To: binutils@sources.redhat.com
Subject: Re: DWARF updates for linker relaxation?
Date: Fri, 28 Jul 2006 23:28:00 -0000	[thread overview]
Message-ID: <44CA9D81.7000201@tensilica.com> (raw)
In-Reply-To: <44BC01FE.1010303@tensilica.com>

[-- Attachment #1: Type: text/plain, Size: 1515 bytes --]

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.


[-- Attachment #2: dwarf-linkrelax.diff --]
[-- Type: text/plain, Size: 4662 bytes --]

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.  */
 

  reply	other threads:[~2006-07-28 23:28 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-07-17 21:32 Bob Wilson
2006-07-28 23:28 ` Bob Wilson [this message]
2006-08-08 10:16   ` Nick Clifton
2006-08-09  0:12     ` Bob Wilson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=44CA9D81.7000201@tensilica.com \
    --to=bwilson@tensilica.com \
    --cc=binutils@sources.redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).