From patchwork Wed Dec 14 02:58:03 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Maciej W. Rozycki" X-Patchwork-Id: 131289 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 7F5DE1007D3 for ; Wed, 14 Dec 2011 13:58:46 +1100 (EST) Received: (qmail 3109 invoked by alias); 14 Dec 2011 02:58:43 -0000 Received: (qmail 3099 invoked by uid 22791); 14 Dec 2011 02:58:41 -0000 X-SWARE-Spam-Status: No, hits=-1.5 required=5.0 tests=AWL, BAYES_00, FROM_12LTRDOM X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 14 Dec 2011 02:58:16 +0000 Received: from svr-orw-fem-01.mgc.mentorg.com ([147.34.98.93]) by relay1.mentorg.com with esmtp id 1Raf2t-0001rz-CL from Maciej_Rozycki@mentor.com ; Tue, 13 Dec 2011 18:58:15 -0800 Received: from SVR-IES-FEM-01.mgc.mentorg.com ([137.202.0.104]) by svr-orw-fem-01.mgc.mentorg.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.4675); Tue, 13 Dec 2011 18:58:15 -0800 Received: from [172.30.7.78] (137.202.0.76) by SVR-IES-FEM-01.mgc.mentorg.com (137.202.0.104) with Microsoft SMTP Server id 14.1.289.1; Wed, 14 Dec 2011 02:58:12 +0000 Date: Wed, 14 Dec 2011 02:58:03 +0000 From: "Maciej W. Rozycki" To: CC: Richard Sandiford , Catherine Moore Subject: [PATCH] MIPS16: Fix truncated DWARF-2 line information Message-ID: User-Agent: Alpine 1.10 (DEB 962 2008-03-14) MIME-Version: 1.0 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi, I've noticed in the presence of a specific MIPS16 function thunk, GCC fails to emit suitable DWARF-2 location directives, which in turn causes DWARF-2 line records to provide truncated information. This is probably best illustrated with an example. Given the following source code: $ cat sinfrob16.c int i; double sinfrob16(double d) { i++; return d; } we get this: $ mips-linux-gnu-gcc -mips16 -Wa,-call_nonpic -fPIC -G0 -g -S sinfrob16.c $ cat sinfrob16.s .section .mdebug.abi32 .previous .gnu_attribute 4, 1 .abicalls .text $Ltext0: .cfi_sections .debug_frame .comm i,4,4 .align 2 .globl sinfrob16 $LFB0 = . .file 1 "sinfrob16.c" .loc 1 4 0 .cfi_startproc # Stub function for sinfrob16 (double) .section .mips16.fn.sinfrob16,"ax",@progbits .align 2 .set nomips16 .ent __fn_stub_sinfrob16 .type __fn_stub_sinfrob16, @function __fn_stub_sinfrob16: .set noreorder .cpload $25 .set reorder .reloc 0,R_MIPS_NONE,sinfrob16 la $25,__fn_local_sinfrob16 mfc1 $5,$f12 mfc1 $4,$f13 jr $25 .end __fn_stub_sinfrob16 __fn_local_sinfrob16 = sinfrob16 .text .set mips16 .ent sinfrob16 .type sinfrob16, @function sinfrob16: .frame $17,8,$31 # vars= 0, regs= 2/0, args= 0, gp= 0 .mask 0x80020000,-4 .fmask 0x00000000,0 li $2,%hi(_gp_disp) addiu $3,$pc,%lo(_gp_disp) sll $2,16 addu $2,$3 save 8,$17,$31 $LCFI0 = . .cfi_def_cfa_offset 8 .cfi_offset 31, -4 .cfi_offset 17, -8 move $17,$sp $LCFI1 = . .cfi_def_cfa_register 17 move $28,$2 .loc 1 5 0 move $2,$28 move $24,$2 .loc 1 4 0 sw $5,12($17) sw $4,8($17) .loc 1 5 0 move $3,$24 lw $2,%got(i)($3) lw $2,0($2) addiu $2,1 move $3,$24 lw $3,%got(i)($3) move $24,$3 move $3,$24 sw $2,0($3) .loc 1 6 0 lw $3,12($17) lw $2,8($17) move $25,$3 move $24,$2 move $3,$25 move $2,$24 move $25,$3 move $24,$2 .loc 1 7 0 move $3,$25 move $2,$24 move $6,$28 lw $6,%got(__mips16_ret_df)($6) jalr $6 lw $6,0($17) move $28,$6 move $sp,$17 $LCFI2 = . .cfi_def_cfa_register 29 restore 8,$17,$31 $LCFI3 = . .cfi_restore 17 .cfi_restore 31 .cfi_def_cfa_offset 0 j $31 .end sinfrob16 .cfi_endproc $LFE0: .size sinfrob16, .-sinfrob16 $Letext0: .section .debug_info,"",@progbits $Ldebug_info0: .4byte 0x6f .2byte 0x2 .4byte $Ldebug_abbrev0 .byte 0x4 .uleb128 0x1 .4byte $LASF1 .byte 0x1 .4byte $LASF2 .4byte $LASF3 .4byte $Ldebug_ranges0+0 .4byte 0 .4byte 0 .4byte $Ldebug_line0 .uleb128 0x2 .byte 0x1 .4byte $LASF4 .byte 0x1 .byte 0x3 .byte 0x1 .4byte 0x54 .4byte $LFB0 .4byte $LFE0 .4byte $LLST0 .byte 0x1 .4byte 0x54 .uleb128 0x3 .ascii "d\000" .byte 0x1 .byte 0x3 .4byte 0x54 .byte 0x2 .byte 0x91 .sleb128 0 .byte 0 .uleb128 0x4 .byte 0x8 .byte 0x4 .4byte $LASF0 .uleb128 0x5 .ascii "i\000" .byte 0x1 .byte 0x1 .4byte 0x6b .byte 0x1 .byte 0x5 .byte 0x3 .4byte i .uleb128 0x6 .byte 0x4 .byte 0x5 .ascii "int\000" .byte 0 .section .debug_abbrev,"",@progbits $Ldebug_abbrev0: .uleb128 0x1 .uleb128 0x11 .byte 0x1 .uleb128 0x25 .uleb128 0xe .uleb128 0x13 .uleb128 0xb .uleb128 0x3 .uleb128 0xe .uleb128 0x1b .uleb128 0xe .uleb128 0x55 .uleb128 0x6 .uleb128 0x11 .uleb128 0x1 .uleb128 0x52 .uleb128 0x1 .uleb128 0x10 .uleb128 0x6 .byte 0 .byte 0 .uleb128 0x2 .uleb128 0x2e .byte 0x1 .uleb128 0x3f .uleb128 0xc .uleb128 0x3 .uleb128 0xe .uleb128 0x3a .uleb128 0xb .uleb128 0x3b .uleb128 0xb .uleb128 0x27 .uleb128 0xc .uleb128 0x49 .uleb128 0x13 .uleb128 0x11 .uleb128 0x1 .uleb128 0x12 .uleb128 0x1 .uleb128 0x40 .uleb128 0x6 .uleb128 0x2116 .uleb128 0xc .uleb128 0x1 .uleb128 0x13 .byte 0 .byte 0 .uleb128 0x3 .uleb128 0x5 .byte 0 .uleb128 0x3 .uleb128 0x8 .uleb128 0x3a .uleb128 0xb .uleb128 0x3b .uleb128 0xb .uleb128 0x49 .uleb128 0x13 .uleb128 0x2 .uleb128 0xa .byte 0 .byte 0 .uleb128 0x4 .uleb128 0x24 .byte 0 .uleb128 0xb .uleb128 0xb .uleb128 0x3e .uleb128 0xb .uleb128 0x3 .uleb128 0xe .byte 0 .byte 0 .uleb128 0x5 .uleb128 0x34 .byte 0 .uleb128 0x3 .uleb128 0x8 .uleb128 0x3a .uleb128 0xb .uleb128 0x3b .uleb128 0xb .uleb128 0x49 .uleb128 0x13 .uleb128 0x3f .uleb128 0xc .uleb128 0x2 .uleb128 0xa .byte 0 .byte 0 .uleb128 0x6 .uleb128 0x24 .byte 0 .uleb128 0xb .uleb128 0xb .uleb128 0x3e .uleb128 0xb .uleb128 0x3 .uleb128 0x8 .byte 0 .byte 0 .byte 0 .section .debug_loc,"",@progbits $Ldebug_loc0: $LLST0: .4byte $LFB0 .4byte $LCFI0 .2byte 0x2 .byte 0x8d .sleb128 0 .4byte $LCFI0 .4byte $LCFI1 .2byte 0x2 .byte 0x8d .sleb128 8 .4byte $LCFI1 .4byte $LCFI2 .2byte 0x2 .byte 0x81 .sleb128 8 .4byte $LCFI2 .4byte $LCFI3 .2byte 0x2 .byte 0x8d .sleb128 8 .4byte $LCFI3 .4byte $LFE0 .2byte 0x2 .byte 0x8d .sleb128 0 .4byte 0 .4byte 0 .section .debug_aranges,"",@progbits .4byte 0x1c .2byte 0x2 .4byte $Ldebug_info0 .byte 0x4 .byte 0 .2byte 0 .2byte 0 .4byte $Ltext0 .4byte $Letext0-$Ltext0 .4byte 0 .4byte 0 .section .debug_ranges,"",@progbits $Ldebug_ranges0: .4byte $Ltext0 .4byte $Letext0 .4byte 0 .4byte 0 .section .debug_line,"",@progbits $Ldebug_line0: .section .debug_str,"MS",@progbits,1 $LASF2: .ascii "sinfrob16.c\000" $LASF3: .ascii "/home/macro/mips-linux/sin\000" $LASF4: .ascii "sinfrob16\000" $LASF1: .ascii "GNU C 4.7.0 20111212 (experimental)\000" $LASF0: .ascii "double\000" .ident "GCC: 4.7.0 20111212 (experimental)" Note that as far as DWARF-2 information is concerned we have a single procedure here, split across two sections. Further processing yields this: $ mips-linux-gnu-gcc -mips16 -Wa,-call_nonpic -fPIC -G0 -g -c sinfrob16.c $ mips-linux-gnu-readelf -wl sinfrob16.o Raw dump of debug contents of section .debug_line: Offset: 0x0 Length: 71 DWARF Version: 2 Prologue Length: 34 Minimum Instruction Length: 1 Initial value of 'is_stmt': 1 Line Base: -5 Line Range: 14 Opcode Base: 13 Opcodes: Opcode 1 has 0 args Opcode 2 has 1 args Opcode 3 has 1 args Opcode 4 has 1 args Opcode 5 has 1 args Opcode 6 has 0 args Opcode 7 has 0 args Opcode 8 has 0 args Opcode 9 has 1 args Opcode 10 has 0 args Opcode 11 has 0 args Opcode 12 has 1 args The Directory Table is empty. The File Name Table: Entry Dir Time Size Name 1 0 0 0 sinfrob16.c Line Number Statements: Extended opcode 2: set Address to 0x0 Special opcode 8: advance Address by 0 to 0x0 and Line by 3 to 4 Advance PC by 32 to 0x20 Extended opcode 1: End of Sequence Extended opcode 2: set Address to 0x15 Special opcode 9: advance Address by 0 to 0x15 and Line by 4 to 5 Special opcode 60: advance Address by 4 to 0x19 and Line by -1 to 4 Special opcode 62: advance Address by 4 to 0x1d and Line by 1 to 5 Advance PC by constant 17 to 0x2e Special opcode 76: advance Address by 5 to 0x33 and Line by 1 to 6 Special opcode 230: advance Address by 16 to 0x43 and Line by 1 to 7 Advance PC by 21 to 0x58 Extended opcode 1: End of Sequence Oops! Where are bits (function prologue) between 0x0 and 0x15 in .text? This indeed breaks in GDB: (gdb) info line sinfrob16 No line number information available. (gdb) info line *sinfrob16+0x15 Line 5 of "sinfrob16.c" starts at address 0x14 and ends at 0x18 . (gdb) After some thinking I decided the simplest approach will be just emitting the missing location directive in the context of the MIPS16 thunk being built that will apply to the actual function prologue. The resulting change is included below -- this just repeats the record originally output before the thunk (and which applies to .mips16.fn.sinfrob16 section). With this in place I'm getting this: $ mips-linux-gnu-gcc -mips16 -Wa,-call_nonpic -fPIC -G0 -g -S sinfrob16.c $ cat sinfrob16.s .section .mdebug.abi32 .previous .gnu_attribute 4, 1 .abicalls .text $Ltext0: .cfi_sections .debug_frame .comm i,4,4 .align 2 .globl sinfrob16 $LFB0 = . .file 1 "sinfrob16.c" .loc 1 4 0 .cfi_startproc # Stub function for sinfrob16 (double) .section .mips16.fn.sinfrob16,"ax",@progbits .align 2 .set nomips16 .ent __fn_stub_sinfrob16 .type __fn_stub_sinfrob16, @function __fn_stub_sinfrob16: .set noreorder .cpload $25 .set reorder .reloc 0,R_MIPS_NONE,sinfrob16 la $25,__fn_local_sinfrob16 mfc1 $5,$f12 mfc1 $4,$f13 jr $25 .end __fn_stub_sinfrob16 __fn_local_sinfrob16 = sinfrob16 .text .loc 1 4 0 .set mips16 .ent sinfrob16 .type sinfrob16, @function sinfrob16: .frame $17,8,$31 # vars= 0, regs= 2/0, args= 0, gp= 0 .mask 0x80020000,-4 .fmask 0x00000000,0 li $2,%hi(_gp_disp) addiu $3,$pc,%lo(_gp_disp) sll $2,16 addu $2,$3 save 8,$17,$31 $LCFI0 = . .cfi_def_cfa_offset 8 .cfi_offset 31, -4 .cfi_offset 17, -8 move $17,$sp $LCFI1 = . .cfi_def_cfa_register 17 move $28,$2 .loc 1 5 0 move $2,$28 move $24,$2 .loc 1 4 0 sw $5,12($17) sw $4,8($17) .loc 1 5 0 move $3,$24 lw $2,%got(i)($3) lw $2,0($2) addiu $2,1 move $3,$24 lw $3,%got(i)($3) move $24,$3 move $3,$24 sw $2,0($3) .loc 1 6 0 lw $3,12($17) lw $2,8($17) move $25,$3 move $24,$2 move $3,$25 move $2,$24 move $25,$3 move $24,$2 .loc 1 7 0 move $3,$25 move $2,$24 move $6,$28 lw $6,%got(__mips16_ret_df)($6) jalr $6 lw $6,0($17) move $28,$6 move $sp,$17 $LCFI2 = . .cfi_def_cfa_register 29 restore 8,$17,$31 $LCFI3 = . .cfi_restore 17 .cfi_restore 31 .cfi_def_cfa_offset 0 j $31 .end sinfrob16 .cfi_endproc $LFE0: .size sinfrob16, .-sinfrob16 $Letext0: .section .debug_info,"",@progbits $Ldebug_info0: .4byte 0x6f .2byte 0x2 .4byte $Ldebug_abbrev0 .byte 0x4 .uleb128 0x1 .4byte $LASF1 .byte 0x1 .4byte $LASF2 .4byte $LASF3 .4byte $Ldebug_ranges0+0 .4byte 0 .4byte 0 .4byte $Ldebug_line0 .uleb128 0x2 .byte 0x1 .4byte $LASF4 .byte 0x1 .byte 0x3 .byte 0x1 .4byte 0x54 .4byte $LFB0 .4byte $LFE0 .4byte $LLST0 .byte 0x1 .4byte 0x54 .uleb128 0x3 .ascii "d\000" .byte 0x1 .byte 0x3 .4byte 0x54 .byte 0x2 .byte 0x91 .sleb128 0 .byte 0 .uleb128 0x4 .byte 0x8 .byte 0x4 .4byte $LASF0 .uleb128 0x5 .ascii "i\000" .byte 0x1 .byte 0x1 .4byte 0x6b .byte 0x1 .byte 0x5 .byte 0x3 .4byte i .uleb128 0x6 .byte 0x4 .byte 0x5 .ascii "int\000" .byte 0 .section .debug_abbrev,"",@progbits $Ldebug_abbrev0: .uleb128 0x1 .uleb128 0x11 .byte 0x1 .uleb128 0x25 .uleb128 0xe .uleb128 0x13 .uleb128 0xb .uleb128 0x3 .uleb128 0xe .uleb128 0x1b .uleb128 0xe .uleb128 0x55 .uleb128 0x6 .uleb128 0x11 .uleb128 0x1 .uleb128 0x52 .uleb128 0x1 .uleb128 0x10 .uleb128 0x6 .byte 0 .byte 0 .uleb128 0x2 .uleb128 0x2e .byte 0x1 .uleb128 0x3f .uleb128 0xc .uleb128 0x3 .uleb128 0xe .uleb128 0x3a .uleb128 0xb .uleb128 0x3b .uleb128 0xb .uleb128 0x27 .uleb128 0xc .uleb128 0x49 .uleb128 0x13 .uleb128 0x11 .uleb128 0x1 .uleb128 0x12 .uleb128 0x1 .uleb128 0x40 .uleb128 0x6 .uleb128 0x2116 .uleb128 0xc .uleb128 0x1 .uleb128 0x13 .byte 0 .byte 0 .uleb128 0x3 .uleb128 0x5 .byte 0 .uleb128 0x3 .uleb128 0x8 .uleb128 0x3a .uleb128 0xb .uleb128 0x3b .uleb128 0xb .uleb128 0x49 .uleb128 0x13 .uleb128 0x2 .uleb128 0xa .byte 0 .byte 0 .uleb128 0x4 .uleb128 0x24 .byte 0 .uleb128 0xb .uleb128 0xb .uleb128 0x3e .uleb128 0xb .uleb128 0x3 .uleb128 0xe .byte 0 .byte 0 .uleb128 0x5 .uleb128 0x34 .byte 0 .uleb128 0x3 .uleb128 0x8 .uleb128 0x3a .uleb128 0xb .uleb128 0x3b .uleb128 0xb .uleb128 0x49 .uleb128 0x13 .uleb128 0x3f .uleb128 0xc .uleb128 0x2 .uleb128 0xa .byte 0 .byte 0 .uleb128 0x6 .uleb128 0x24 .byte 0 .uleb128 0xb .uleb128 0xb .uleb128 0x3e .uleb128 0xb .uleb128 0x3 .uleb128 0x8 .byte 0 .byte 0 .byte 0 .section .debug_loc,"",@progbits $Ldebug_loc0: $LLST0: .4byte $LFB0 .4byte $LCFI0 .2byte 0x2 .byte 0x8d .sleb128 0 .4byte $LCFI0 .4byte $LCFI1 .2byte 0x2 .byte 0x8d .sleb128 8 .4byte $LCFI1 .4byte $LCFI2 .2byte 0x2 .byte 0x81 .sleb128 8 .4byte $LCFI2 .4byte $LCFI3 .2byte 0x2 .byte 0x8d .sleb128 8 .4byte $LCFI3 .4byte $LFE0 .2byte 0x2 .byte 0x8d .sleb128 0 .4byte 0 .4byte 0 .section .debug_aranges,"",@progbits .4byte 0x1c .2byte 0x2 .4byte $Ldebug_info0 .byte 0x4 .byte 0 .2byte 0 .2byte 0 .4byte $Ltext0 .4byte $Letext0-$Ltext0 .4byte 0 .4byte 0 .section .debug_ranges,"",@progbits $Ldebug_ranges0: .4byte $Ltext0 .4byte $Letext0 .4byte 0 .4byte 0 .section .debug_line,"",@progbits $Ldebug_line0: .section .debug_str,"MS",@progbits,1 $LASF2: .ascii "sinfrob16.c\000" $LASF3: .ascii "/home/macro/mips-linux/sin\000" $LASF4: .ascii "sinfrob16\000" $LASF1: .ascii "GNU C 4.7.0 20111212 (experimental)\000" $LASF0: .ascii "double\000" .ident "GCC: 4.7.0 20111212 (experimental)" $ mips-linux-gnu-gcc -mips16 -Wa,-call_nonpic -fPIC -G0 -g -c sinfrob16.c $ mips-linux-gnu-readelf -wl sinfrob16.o Raw dump of debug contents of section .debug_line: Offset: 0x0 Length: 73 DWARF Version: 2 Prologue Length: 34 Minimum Instruction Length: 1 Initial value of 'is_stmt': 1 Line Base: -5 Line Range: 14 Opcode Base: 13 Opcodes: Opcode 1 has 0 args Opcode 2 has 1 args Opcode 3 has 1 args Opcode 4 has 1 args Opcode 5 has 1 args Opcode 6 has 0 args Opcode 7 has 0 args Opcode 8 has 0 args Opcode 9 has 1 args Opcode 10 has 0 args Opcode 11 has 0 args Opcode 12 has 1 args The Directory Table is empty. The File Name Table: Entry Dir Time Size Name 1 0 0 0 sinfrob16.c Line Number Statements: Extended opcode 2: set Address to 0x0 Special opcode 8: advance Address by 0 to 0x0 and Line by 3 to 4 Advance PC by 32 to 0x20 Extended opcode 1: End of Sequence Extended opcode 2: set Address to 0x1 Special opcode 8: advance Address by 0 to 0x1 and Line by 3 to 4 Advance PC by constant 17 to 0x12 Special opcode 48: advance Address by 3 to 0x15 and Line by 1 to 5 Special opcode 60: advance Address by 4 to 0x19 and Line by -1 to 4 Special opcode 62: advance Address by 4 to 0x1d and Line by 1 to 5 Advance PC by constant 17 to 0x2e Special opcode 76: advance Address by 5 to 0x33 and Line by 1 to 6 Special opcode 230: advance Address by 16 to 0x43 and Line by 1 to 7 Advance PC by 21 to 0x58 Extended opcode 1: End of Sequence (gdb) info line sinfrob16 Line 4 of "sinfrob16.c" starts at address 0x0 and ends at 0x14 . (gdb) info line *sinfrob16+0x15 Line 5 of "sinfrob16.c" starts at address 0x14 and ends at 0x18 . (gdb) Regression-testing this change turned out to be quite tricky as current trunk does not appear to build for the mips-sde-elf target: /home/macro/mips-sde/obj/gcc/./gcc/xgcc -B/home/macro/mips-sde/obj/gcc/./gcc/ -B/home/macro/mips-sde/install/mips-sde-elf/bin/ -B/home/macro/mips-sde/install/mips-sde-elf/lib/ -isystem /home/macro/mips-sde/install/mips-sde-elf/include -isystem /home/macro/mips-sde/install/mips-sde-elf/sys-include --sysroot=/home/macro/mips-sde/install/mips-sde-elf -g -O2 -Os -minterlink-mips16 -mcode-xonly -mno-gpopt -EL -mips16 -O2 -g -O2 -Os -minterlink-mips16 -mcode-xonly -mno-gpopt -DIN_GCC -DCROSS_DIRECTORY_STRUCTURE -W -Wall -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -I. -I. -I../../../.././gcc -I/home/macro/mips-sde/src/gcc/libgcc -I/home/macro/mips-sde/src/gcc/libgcc/. -I/home/macro/mips-sde/src/gcc/libgcc/../gcc -I/home/macro/mips-sde/src/gcc/libgcc/../include -o _ashldi3.o -MT _ashldi3.o -MD -MP -MF _ashldi3.dep -DL_ashldi3 -c /home/macro/mips-sde/src/gcc/libgcc/libgcc2.c /home/macro/mips-sde/src/gcc/libgcc/libgcc2.c: In function '__muldi3': /home/macro/mips-sde/src/gcc/libgcc/libgcc2.c:559:1: error: unrecognizable insn: (insn 49 48 17 2 (set (reg:SI 235 [ __x+4 ]) (subreg:SI (reg:DI 64 lo) 4)) /home/macro/mips-sde/src/gcc/libgcc/libgcc2.c:553 -1 (nil)) /home/macro/mips-sde/src/gcc/libgcc/libgcc2.c:559:1: internal compiler error: in extract_insn, at recog.c:2123 and the mips-linux-gnu configuration is not ready yet for MIPS16 testing. I did regression test it with 4.5 though -- which is the version I originally developed this fix for -- for mips-sde-elf and the default (MIPS32) and MIPS16 multilibs, with no change in results. I chose the GDB test suite rather than the GCC one though, as this change does not affect code generation and the GCC tests do not really depend that much on the subtleties of DWARF-2 information. This problem most prominently manifests itself with source-level single-stepping, where instead of stepping into a function affected (such as sinfrob16 above) GDB skips over it as it believes the function has no debug information available. And single-stepping is only really covered with the GDB test suite (furthermore the case above is only triggered where MIPS32/MIPS16 interlinking and hard FP code is used, which is not easily covered and currently not at all by any test suite, so this verification only really checked if my change hasn't broken anything fundamentally). All the sinfrob16 manual verification above was done with current trunk. I hope this is good enough -- given the circumstances -- and suitable for stage 3 as a fix for a long-standing bug. OK to apply? 2011-12-14 Maciej W. Rozycki gcc/ * config/mips/mips.c (mips16_build_function_stub): Emit source line debug information once the thunk has been produced. Maciej gcc-mips16-dwarf2-line.patch Index: gcc-fsf-trunk-quilt/gcc/config/mips/mips.c =================================================================== --- gcc-fsf-trunk-quilt.orig/gcc/config/mips/mips.c 2011-12-13 05:02:12.605606194 +0000 +++ gcc-fsf-trunk-quilt/gcc/config/mips/mips.c 2011-12-13 05:08:42.915611245 +0000 @@ -6032,6 +6032,9 @@ mips16_build_function_stub (void) within this file. */ ASM_OUTPUT_DEF (asm_out_file, alias_name, fnname); + debug_hooks->source_line (locator_line (prologue_locator), + locator_file (prologue_locator), 0, true); + switch_to_section (function_section (current_function_decl)); }