From 1737851b2005af535e44e89a4e7f341eddddd0f0 Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Tue, 8 Aug 2006 19:09:34 +0000 Subject: [PATCH] gas/ChangeLog: * 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 | 9 ++++ gas/config/tc-xtensa.h | 3 ++ gas/dwarf2dbg.c | 65 +++++++++++++++++++++++- gas/testsuite/ChangeLog | 5 ++ gas/testsuite/gas/lns/lns-common-1-alt.d | 39 ++++++++++++++ gas/testsuite/gas/lns/lns.exp | 7 ++- 6 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 gas/testsuite/gas/lns/lns-common-1-alt.d diff --git a/gas/ChangeLog b/gas/ChangeLog index f4430b2c3d4..07c02c14687 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,12 @@ +2006-08-08 Bob Wilson + + * 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 * config/tc-sh.c (sh_frob_section): Canonicalize pointers to local diff --git a/gas/config/tc-xtensa.h b/gas/config/tc-xtensa.h index 71f1ebbd3b3..838a9ad07cb 100644 --- a/gas/config/tc-xtensa.h +++ b/gas/config/tc-xtensa.h @@ -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. */ diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c index 22dde6a0194..eb9584b615b 100644 --- a/gas/dwarf2dbg.c +++ b/gas/dwarf2dbg.c @@ -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); @@ -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 { diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 5431c5a30a3..63a4c0d703f 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-08-08 Bob Wilson + + * 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 * 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 index 00000000000..f76e8528ce3 --- /dev/null +++ b/gas/testsuite/gas/lns/lns-common-1-alt.d @@ -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 +#... diff --git a/gas/testsuite/gas/lns/lns.exp b/gas/testsuite/gas/lns/lns.exp index 1bc95990e3e..8a87914405d 100644 --- a/gas/testsuite/gas/lns/lns.exp +++ b/gas/testsuite/gas/lns/lns.exp @@ -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" + } } -- 2.30.2