summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog16
-rw-r--r--gas/config/tc-h8300.h1
-rw-r--r--gas/dwarf2dbg.c38
-rw-r--r--gas/testsuite/ChangeLog7
-rw-r--r--gas/testsuite/gas/lns/lns-big-delta.d4
-rw-r--r--gas/testsuite/gas/lns/lns.exp5
-rw-r--r--gas/write.c7
7 files changed, 69 insertions, 9 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 4149ba35b6..0d833a9e5f 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,19 @@
+2012-06-28 Nick Clifton <nickc@redhat.com>
+
+ * dwarf2dbg.c (DWARF2_USE_FIXED_ADVANCE_PC): Enable when using
+ linker relaxation.
+ (dwarf2_gen_line_info): Generate real, local, labels for line
+ numbers.
+ (dwarf2dbg_convert_frag): Do not finalize the computation of the
+ frag's symbol value when linker relaxation is enabled.
+ (ADDR_DELTA_LIMIT): Define.
+ (size_fixed_inc_line_addr): Use ADDR_DELTA_LIMIT.
+ (emit_fixed_inc_line_addr): Likewise.
+ * write.c (fixup_segment): If the subtraction of two symbols
+ cannot be resolved but is valid, then prevent bogus range warnings
+ by pre-biasing add_number.
+ * config/tc-h8300.h (DWARF2_USE_FIXED_ADVANCE_PC): Define to 0.
+
2012-06-22 Roland McGrath <mcgrathr@google.com>
* NEWS: Mention 'rep ret' too.
diff --git a/gas/config/tc-h8300.h b/gas/config/tc-h8300.h
index 73d4840963..f86cf94a3e 100644
--- a/gas/config/tc-h8300.h
+++ b/gas/config/tc-h8300.h
@@ -51,6 +51,7 @@ struct internal_reloc;
/* Minimum instruction is of 16 bits. */
#define DWARF2_LINE_MIN_INSN_LENGTH 2
+#define DWARF2_USE_FIXED_ADVANCE_PC 0
#ifdef OBJ_ELF
/* Provide mappings from the original H8 COFF relocation names to
diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c
index f428f0d122..2ec329abc1 100644
--- a/gas/dwarf2dbg.c
+++ b/gas/dwarf2dbg.c
@@ -119,7 +119,7 @@
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
+# define DWARF2_USE_FIXED_ADVANCE_PC linkrelax
#endif
/* First special line opcde - leave room for the standard opcodes.
@@ -361,7 +361,17 @@ dwarf2_gen_line_info (addressT ofs, struct dwarf2_line_info *loc)
filenum = loc->filenum;
dwarf2_push_line (loc);
- dwarf2_flush_pending_lines (symbol_temp_new (now_seg, ofs, frag_now));
+ if (linkrelax)
+ {
+ char name[120];
+
+ /* Use a non-fake name for the line number location,
+ so that it can be referred to by relocations. */
+ sprintf (name, ".Loc.%u.%u", line, filenum);
+ dwarf2_flush_pending_lines (symbol_new (name, now_seg, ofs, frag_now));
+ }
+ else
+ dwarf2_flush_pending_lines (symbol_temp_new (now_seg, ofs, frag_now));
}
/* Returns the current source information. If .file directives have
@@ -1064,6 +1074,7 @@ out_inc_line_addr (int line_delta, addressT addr_delta)
line and address information, but it is required if linker relaxation
could change the code offsets. The following two routines *must* be
kept in sync. */
+#define ADDR_DELTA_LIMIT 50000
static int
size_fixed_inc_line_addr (int line_delta, addressT addr_delta)
@@ -1074,7 +1085,7 @@ size_fixed_inc_line_addr (int line_delta, addressT addr_delta)
if (line_delta != INT_MAX)
len = 1 + sizeof_leb128 (line_delta, 1);
- if (addr_delta > 50000)
+ if (addr_delta > ADDR_DELTA_LIMIT)
{
/* DW_LNS_extended_op */
len += 1 + sizeof_leb128 (sizeof_address + 1, 0);
@@ -1122,7 +1133,7 @@ emit_fixed_inc_line_addr (int line_delta, addressT addr_delta, fragS *frag,
which this function would not be used) could change the operand by
an unknown amount. If the address increment is getting close to
the limit, just reset the address. */
- if (addr_delta > 50000)
+ if (addr_delta > ADDR_DELTA_LIMIT)
{
symbolS *to_sym;
expressionS exp;
@@ -1231,7 +1242,24 @@ dwarf2dbg_convert_frag (fragS *frag)
{
offsetT addr_diff;
- addr_diff = resolve_symbol_value (frag->fr_symbol);
+ if (DWARF2_USE_FIXED_ADVANCE_PC)
+ {
+ /* If linker relaxation is enabled then the distance bewteen the two
+ symbols in the frag->fr_symbol expression might change. Hence we
+ cannot rely upon the value computed by resolve_symbol_value.
+ Instead we leave the expression unfinalized and allow
+ emit_fixed_inc_line_addr to create a fixup (which later becomes a
+ relocation) that will allow the linker to correctly compute the
+ actual address difference. We have to use a fixed line advance for
+ this as we cannot (easily) relocate leb128 encoded values. */
+ int saved_finalize_syms = finalize_syms;
+
+ finalize_syms = 0;
+ addr_diff = resolve_symbol_value (frag->fr_symbol);
+ finalize_syms = saved_finalize_syms;
+ }
+ else
+ addr_diff = resolve_symbol_value (frag->fr_symbol);
/* fr_var carries the max_chars that we created the fragment with.
fr_subtype carries the current expected length. We must, of
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 729b748bb9..d76f013451 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2012-06-28 Nick Clifton <nickc@redhat.com>
+
+ * gas/lns/lns.exp: Use alternate lns-common test for targets
+ enabling linker relaxation.
+ * gas/lns/lns-big-delta.d: Allow for output from architectures
+ with 32-bit addresses.
+
2012-06-27 Alan Modra <amodra@gmail.com>
* gas/i386/rep-ret.s: Zero pad section.
diff --git a/gas/testsuite/gas/lns/lns-big-delta.d b/gas/testsuite/gas/lns/lns-big-delta.d
index 43b48d89e2..b6a113e811 100644
--- a/gas/testsuite/gas/lns/lns-big-delta.d
+++ b/gas/testsuite/gas/lns/lns-big-delta.d
@@ -10,8 +10,8 @@ Raw dump of debug contents of section \.debug_line:
Advance PC by fixed size amount 0 to 0x0
Copy
Advance Line by 1 to 3
- Extended opcode 2: set Address to 0x124fc
+ Extended opcode 2: set Address to 0x.....
Copy
- Advance PC by fixed size amount 4 to 0x12500
+ Advance PC by fixed size amount . to 0x.....
Extended opcode 1: End of Sequence
#pass
diff --git a/gas/testsuite/gas/lns/lns.exp b/gas/testsuite/gas/lns/lns.exp
index 4fba663c85..30e2688245 100644
--- a/gas/testsuite/gas/lns/lns.exp
+++ b/gas/testsuite/gas/lns/lns.exp
@@ -17,7 +17,10 @@ if {
&& ![istarget s390*-*-*]
} {
# Use alternate file for targets using DW_LNS_fixed_advance_pc opcodes.
- if { [istarget xtensa*-*-*] } {
+ if { [istarget xtensa*-*-*]
+ || [istarget am3*-*-*]
+ || [istarget cr16-*-*]
+ || [istarget mn10*-*-*] } {
run_dump_test "lns-common-1-alt"
run_dump_test "lns-big-delta"
} elseif { [istarget ia64*-*-*] } {
diff --git a/gas/write.c b/gas/write.c
index 23d4334289..7fb2e8bb3b 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -1004,7 +1004,12 @@ fixup_segment (fixS *fixP, segT this_segment)
fixP->fx_subsy = NULL;
fixP->fx_pcrel = 1;
}
- else if (!TC_VALIDATE_FIX_SUB (fixP, add_symbol_segment))
+ else if (TC_VALIDATE_FIX_SUB (fixP, add_symbol_segment))
+ /* If the fix is valid, subtract fx_subsy here. The addition of
+ fx_addsy will be performed below. Doing this prevents bogus
+ warnings from the range check below. */
+ add_number -= S_GET_VALUE (fixP->fx_subsy);
+ else
{
if (!md_register_arithmetic
&& (add_symbol_segment == reg_section