From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16010 invoked by alias); 9 Jan 2004 06:39:30 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 15991 invoked from network); 9 Jan 2004 06:39:22 -0000 Received: from unknown (HELO bubble.modra.org) (144.136.188.60) by sources.redhat.com with SMTP; 9 Jan 2004 06:39:22 -0000 Received: by bubble.modra.org (Postfix, from userid 500) id 287E37E90F; Fri, 9 Jan 2004 17:09:21 +1030 (CST) Date: Fri, 09 Jan 2004 06:39:00 -0000 From: Alan Modra To: Geoff Keating , cagney@gnu.org, kettenis@chello.nl, gcc-patches@gcc.gnu.org, dje@watson.ibm.com, gdb-patches@sources.redhat.com, Ulrich.Weigand@de.ibm.com Subject: Re: Incorrect DWARF-2 register numbers on PPC64? Message-ID: <20040109063921.GK2969@bubble.modra.org> Mail-Followup-To: Geoff Keating , cagney@gnu.org, kettenis@chello.nl, gcc-patches@gcc.gnu.org, dje@watson.ibm.com, gdb-patches@sources.redhat.com, Ulrich.Weigand@de.ibm.com References: <200312201527.hBKFRHgI000712@elgar.kettenis.dyndns.org> <3FF5A069.1040306@gnu.org> <200401022317.i02NHQBR001191@desire.geoffk.org> <20040106152710.GB2533@bubble.modra.org> <200401071743.i07HhAle000811@elgar.kettenis.dyndns.org> <20040107222907.GO2533@bubble.modra.org> <3FFC97DF.2030009@gnu.org> <20040108004849.GR2533@bubble.modra.org> <200401080501.i0851VBx016440@desire.geoffk.org> <20040109023442.GF2969@bubble.modra.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040109023442.GF2969@bubble.modra.org> User-Agent: Mutt/1.4i X-SW-Source: 2004-01/txt/msg00235.txt.bz2 On Fri, Jan 09, 2004 at 01:04:42PM +1030, Alan Modra wrote: > This means we are stuck with the current > .eh_frame register numbering. It should be possible to fix .debug_frame This version actually works.. The untested one suffered from aborts in rs6000_dbx_register_number due to calling it on invalid values. * config/rs6000/sysv4.h (DWARF2_FRAME_REG_OUT): Define. * dwarf2out.c (output_cfi): Map regs using DWARF2_FRAME_REG_OUT. * doc/tm.texi (DWARF_FRAME_REGNUM, DWARF2_FRAME_REG_OUT): Document. Regression testing on powerpc-linux and powerpc64-linux still in progress. OK for mainline assuming everything passes? Index: gcc/config/rs6000/sysv4.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/rs6000/sysv4.h,v retrieving revision 1.144 diff -u -p -r1.144 sysv4.h --- gcc/config/rs6000/sysv4.h 7 Jan 2004 01:21:28 -0000 1.144 +++ gcc/config/rs6000/sysv4.h 9 Jan 2004 06:08:50 -0000 @@ -744,6 +744,18 @@ extern int fixuplabelno; #define DBX_REGISTER_NUMBER(REGNO) rs6000_dbx_register_number (REGNO) +/* Map register numbers held in the call frame info that gcc has + collected using DWARF_FRAME_REGNUM to those that should be output in + .debug_frame and .eh_frame. We continue to use gcc hard reg numbers + for .eh_frame, but use the numbers mandated by the various ABIs for + .debug_frame. rs6000_emit_prologue has translated any combination of + CR2, CR3, CR4 saves to a save of CR2. The actual code emitted saves + the whole of CR, so we map CR2_REGNO to the DWARF reg for CR. */ +#define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH) \ + ((FOR_EH) ? (REGNO) \ + : (REGNO) == CR2_REGNO ? 64 \ + : DBX_REGISTER_NUMBER (REGNO)) + #define TARGET_ENCODE_SECTION_INFO rs6000_elf_encode_section_info #define TARGET_IN_SMALL_DATA_P rs6000_elf_in_small_data_p #define TARGET_SECTION_TYPE_FLAGS rs6000_elf_section_type_flags Index: gcc/dwarf2out.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v retrieving revision 1.471 diff -u -p -r1.471 dwarf2out.c --- gcc/dwarf2out.c 8 Jan 2004 07:54:11 -0000 1.471 +++ gcc/dwarf2out.c 9 Jan 2004 06:08:43 -0000 @@ -1783,11 +1783,19 @@ dw_cfi_oprnd2_desc (enum dwarf_call_fram #if defined (DWARF2_DEBUGGING_INFO) || defined (DWARF2_UNWIND_INFO) +/* Map register numbers held in the call frame info that gcc has + collected using DWARF_FRAME_REGNUM to those that should be output in + .debug_frame and .eh_frame. */ +#ifndef DWARF2_FRAME_REG_OUT +#define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH) (REGNO) +#endif + /* Output a Call Frame Information opcode and its operand(s). */ static void output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh) { + unsigned long r; if (cfi->dw_cfi_opc == DW_CFA_advance_loc) dw2_asm_output_data (1, (cfi->dw_cfi_opc | (cfi->dw_cfi_oprnd1.dw_cfi_offset & 0x3f)), @@ -1795,17 +1803,17 @@ output_cfi (dw_cfi_ref cfi, dw_fde_ref f cfi->dw_cfi_oprnd1.dw_cfi_offset); else if (cfi->dw_cfi_opc == DW_CFA_offset) { - dw2_asm_output_data (1, (cfi->dw_cfi_opc - | (cfi->dw_cfi_oprnd1.dw_cfi_reg_num & 0x3f)), - "DW_CFA_offset, column 0x%lx", - cfi->dw_cfi_oprnd1.dw_cfi_reg_num); + r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh); + dw2_asm_output_data (1, (cfi->dw_cfi_opc | (r & 0x3f)), + "DW_CFA_offset, column 0x%lx", r); dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL); } else if (cfi->dw_cfi_opc == DW_CFA_restore) - dw2_asm_output_data (1, (cfi->dw_cfi_opc - | (cfi->dw_cfi_oprnd1.dw_cfi_reg_num & 0x3f)), - "DW_CFA_restore, column 0x%lx", - cfi->dw_cfi_oprnd1.dw_cfi_reg_num); + { + r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh); + dw2_asm_output_data (1, (cfi->dw_cfi_opc | (r & 0x3f)), + "DW_CFA_restore, column 0x%lx", r); + } else { dw2_asm_output_data (1, cfi->dw_cfi_opc, @@ -1850,15 +1858,15 @@ output_cfi (dw_cfi_ref cfi, dw_fde_ref f case DW_CFA_offset_extended: case DW_CFA_def_cfa: - dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, - NULL); + r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh); + dw2_asm_output_data_uleb128 (r, NULL); dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL); break; case DW_CFA_offset_extended_sf: case DW_CFA_def_cfa_sf: - dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, - NULL); + r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh); + dw2_asm_output_data_uleb128 (r, NULL); dw2_asm_output_data_sleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL); break; @@ -1866,15 +1874,15 @@ output_cfi (dw_cfi_ref cfi, dw_fde_ref f case DW_CFA_undefined: case DW_CFA_same_value: case DW_CFA_def_cfa_register: - dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, - NULL); + r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh); + dw2_asm_output_data_uleb128 (r, NULL); break; case DW_CFA_register: - dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, - NULL); - dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd2.dw_cfi_reg_num, - NULL); + r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh); + dw2_asm_output_data_uleb128 (r, NULL); + r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd2.dw_cfi_reg_num, for_eh); + dw2_asm_output_data_uleb128 (r, NULL); break; case DW_CFA_def_cfa_offset: @@ -1904,7 +1912,7 @@ output_cfi (dw_cfi_ref cfi, dw_fde_ref f } } -/* Output the call frame information used to used to record information +/* Output the call frame information used to record information that relates to calculating the frame pointer, and records the location of saved registers. */ Index: gcc/doc/tm.texi =================================================================== RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v retrieving revision 1.276 diff -u -p -r1.276 tm.texi --- gcc/doc/tm.texi 30 Dec 2003 20:27:53 -0000 1.276 +++ gcc/doc/tm.texi 9 Jan 2004 06:29:37 -0000 @@ -3289,6 +3289,26 @@ column number to use instead. See the PowerPC's SPE target for an example. @end defmac +@defmac DWARF_FRAME_REGNUM (@var{regno}) + +Define this macro if the target's representation for dwarf registers +used in .eh_frame or .debug_frame is different from that used in other +debug info sections. Given a gcc hard register number, this macro +should return the .eh_frame register number. The default is +@code{DBX_REGISTER_NUMBER (@var{regno})}. + +@end defmac + +@defmac DWARF2_FRAME_REG_OUT (@var{regno}, @var{for_eh}) + +Define this macro to map register numbers held in the call frame info +that gcc has collected using @code{DWARF_FRAME_REGNUM} to those that +should be output in .debug_frame (@code{@var{for_eh}} is zero) and +.eh_frame (@code{@var{for_eh}} is non-zero). The default is to +return @code{@var{regno}}. + +@end defmac + @node Elimination @subsection Eliminating Frame Pointer and Arg Pointer -- Alan Modra IBM OzLabs - Linux Technology Centre