From 453dc3f0101420a5f44b50e4f0425ac8edc64e0c Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 28 Jun 2012 11:31:14 +0000 Subject: [PATCH] * 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. * 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. --- gas/ChangeLog | 16 +++++++++++ gas/config/tc-h8300.h | 1 + gas/dwarf2dbg.c | 38 +++++++++++++++++++++++---- gas/testsuite/ChangeLog | 7 +++++ gas/testsuite/gas/lns/lns-big-delta.d | 4 +-- gas/testsuite/gas/lns/lns.exp | 5 +++- gas/write.c | 7 ++++- 7 files changed, 69 insertions(+), 9 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 4149ba35b6f..0d833a9e5fc 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,19 @@ +2012-06-28 Nick Clifton + + * 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 * NEWS: Mention 'rep ret' too. diff --git a/gas/config/tc-h8300.h b/gas/config/tc-h8300.h index 73d48409631..f86cf94a3e8 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 f428f0d1223..2ec329abc15 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 729b748bb9e..d76f013451b 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2012-06-28 Nick Clifton + + * 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 * 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 43b48d89e25..b6a113e811a 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 4fba663c85a..30e2688245b 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 23d4334289f..7fb2e8bb3b9 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 -- 2.30.2