From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22323 invoked by alias); 28 Jul 2006 23:28:05 -0000 Received: (qmail 22310 invoked by uid 22791); 28 Jul 2006 23:28:04 -0000 X-Spam-Check-By: sourceware.org Received: from hq.tensilica.com (HELO mailapp.tensilica.com) (65.205.227.29) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 28 Jul 2006 23:28:02 +0000 Received: from localhost ([127.0.0.1] ident=amavis) by mailapp.tensilica.com with esmtp (Exim 4.34) id 1G6bkO-0000rE-7h for binutils@sources.redhat.com; Fri, 28 Jul 2006 16:28:00 -0700 Received: from mailapp.tensilica.com ([127.0.0.1]) by localhost (mailapp [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 02408-09 for ; Fri, 28 Jul 2006 16:28:00 -0700 (PDT) Received: from heron.hq.tensilica.com ([192.168.11.123]) by mailapp.tensilica.com with esmtp (Exim 4.34) id 1G6bkN-0000r7-TU for binutils@sources.redhat.com; Fri, 28 Jul 2006 16:27:59 -0700 Received: from [192.168.11.123] (heron.hq.tensilica.com [192.168.11.123]) by heron.hq.tensilica.com (Postfix) with ESMTP id EFD06AC3E1 for ; Fri, 28 Jul 2006 16:28:01 -0700 (PDT) Message-ID: <44CA9D81.7000201@tensilica.com> Date: Fri, 28 Jul 2006 23:28:00 -0000 From: Bob Wilson User-Agent: Thunderbird 1.5.0.4 (X11/20060615) MIME-Version: 1.0 To: binutils@sources.redhat.com Subject: Re: DWARF updates for linker relaxation? In-Reply-To: <44BC01FE.1010303@tensilica.com> Content-Type: multipart/mixed; boundary="------------020101040605050304020606" Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org X-SW-Source: 2006-07/txt/msg00361.txt.bz2 This is a multi-part message in MIME format. --------------020101040605050304020606 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1515 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 * 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. --------------020101040605050304020606 Content-Type: text/plain; name="dwarf-linkrelax.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="dwarf-linkrelax.diff" Content-length: 4662 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. */ --------------020101040605050304020606--