gas/ChangeLog:
authorBob Wilson <bob.wilson@acm.org>
Tue, 8 Aug 2006 19:09:34 +0000 (19:09 +0000)
committerBob Wilson <bob.wilson@acm.org>
Tue, 8 Aug 2006 19:09:34 +0000 (19:09 +0000)
* 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.
gas/testsuite/ChangeLog:
* gas/lns/lns-common-1-alt.d: New file.
* gas/lns/lns.exp: Use lns-common-1-alt.d for xtensa targets.

gas/ChangeLog
gas/config/tc-xtensa.h
gas/dwarf2dbg.c
gas/testsuite/ChangeLog
gas/testsuite/gas/lns/lns-common-1-alt.d [new file with mode: 0644]
gas/testsuite/gas/lns/lns.exp

index f4430b2c3d41520117205b0404f058f31025ab31..07c02c14687d4397640f757685e9b92e56ed9664 100644 (file)
@@ -1,3 +1,12 @@
+2006-08-08  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.
+
 2006-08-08  DJ Delorie  <dj@redhat.com>
 
        * config/tc-sh.c (sh_frob_section): Canonicalize pointers to local
index 71f1ebbd3b383f427147b9fa0dbddd5207ae4862..838a9ad07cbc548d1a40fca2d9b0a401949fb2f3 100644 (file)
@@ -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 22dde6a0194dd56f9025a1cbda7072baa39b906e..eb9584b615b462b0991c3233ff1693abf443e938 100644 (file)
 #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);
@@ -744,6 +753,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
@@ -977,6 +994,45 @@ out_inc_line_addr (int line_delta, addressT addr_delta)
   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.  */
 
@@ -1127,6 +1183,8 @@ process_entries (segT seg, struct line_entry *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
@@ -1146,7 +1204,12 @@ process_entries (segT seg, struct line_entry *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 5431c5a30a37e3b2a21a181610f706ff6e0b0964..63a4c0d703f573fed72b719a17f0d76ab6627118 100644 (file)
@@ -1,3 +1,8 @@
+2006-08-08  Bob Wilson  <bob.wilson@acm.org>
+
+       * gas/lns/lns-common-1-alt.d: New file.
+       * gas/lns/lns.exp: Use lns-common-1-alt.d for xtensa targets.
+
 2006-08-04 Pedro Alves <pedro_alves@portugalmail.pt>
 
        * gas/arm/wince.s: New test.
diff --git a/gas/testsuite/gas/lns/lns-common-1-alt.d b/gas/testsuite/gas/lns/lns-common-1-alt.d
new file mode 100644 (file)
index 0000000..f76e852
--- /dev/null
@@ -0,0 +1,39 @@
+#source: lns-common-1.s
+#readelf: -wl
+#name: lns-common-1
+Dump of debug contents of section \.debug_line:
+#...
+  Initial value of 'is_stmt':  1
+#...
+ Line Number Statements:
+  Extended opcode 2: set Address to .*
+  Copy
+  Set column to 3
+  Advance Line by 1 to 2
+  Advance PC by fixed size amount .* to .*
+  Copy
+  Set prologue_end to true
+  Advance Line by 1 to 3
+  Advance PC by fixed size amount .* to .*
+  Copy
+  Set column to 0
+  Set epilogue_begin to true
+  Advance Line by 1 to 4
+  Advance PC by fixed size amount .* to .*
+  Copy
+  Set ISA to 1
+  Set basic block
+  Advance Line by 1 to 5
+  Advance PC by fixed size amount .* to .*
+  Copy
+  Set is_stmt to 0
+  Advance Line by 1 to 6
+  Advance PC by fixed size amount .* to .*
+  Copy
+  Set is_stmt to 1
+  Advance Line by 1 to 7
+  Advance PC by fixed size amount .* to .*
+  Copy
+  Advance PC by fixed size amount .* to .*
+  Extended opcode 1: End of Sequence
+#...
index 1bc95990e3ea099e2bfd6a17cb854a8a1d41300c..8a87914405d94606d5b801b724605684e4e446b1 100644 (file)
@@ -23,5 +23,10 @@ run_list_test "lns-diag-1" ""
 # defined a macro...
 if { ![istarget ia64*-*-*] && ![istarget i370-*-*] && ![istarget i960-*-*]
      && ![istarget or32-*-*] && ![istarget s390*-*-*] } {
-  run_dump_test "lns-common-1"
+  # Use alternate file for targets using DW_LNS_fixed_advance_pc opcodes.
+  if { [istarget xtensa-*-*] } {
+    run_dump_test "lns-common-1-alt"
+  } else {
+    run_dump_test "lns-common-1"
+  }
 }