http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53276
Bug #: 53276 Summary: DWARF-2 line information truncated for MIPS16 thunks Classification: Unclassified Product: gcc Version: 4.8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target AssignedTo: unassig...@gcc.gnu.org ReportedBy: ma...@linux-mips.org Target: mips-sde-elf, mips-linux-gnu Created attachment 27342 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=27342 MIPS16: Fix truncated DWARF-2 line information Recording the bug here so that it's not lost. This was originally reported here: http://gcc.gnu.org/ml/gcc-patches/2011-12/msg01067.html I have now regression-tested the fix proposed against 4.8.0 20120501, using the mips-sde-elf target (thanks, Richard, for fixing it), for MIPS32 and MIPS16 multilibs, both endiannesses, with the gcc, g++, libstdc++ and gdb test suites. I have tested a little-endian n64 MIPS64 multilib as well, but due to limitations of my environment I could only cover gcc, g++ and libstdc++ test suites (i.e. no gdb, and no big-endian testing either). All the tests were successful. Until recently MIPS16 thunks were not covered by any testing at all, this bug could have only been triggered manually when doing actual debugging. I have recently fixed numerous bugs in GDB related to MIPS16 thunk support and as a part of that added a test case that verifies correct GDB support. GDB relies on correct line information for function prologues and therefore this bug now triggers in that test case. You can restrict the GDB test suite to run gdb.arch/mips16-thunks.exp only to save time if you want to verify correct support; that test case relies on MIPS16 execution support in the target -- that includes a MIPS16 execution unit in the processor used (note QEMU support may not necessarily be reliable enough to run that test case; I don't know for sure) as well as in the environment (that includes the rest of the toolchain, any libraries involved and the OS, as may be necessary). If successful, the test case should score 140 passes. The original report now follows, I have attached the original fix proposal for easier retrieval as well. ------------------------------------------------------------------------------ >From ma...@codesourcery.com Wed Dec 14 02:58:18 2011 Message-ID: <alpine.deb.1.10.1112132001040.5...@tp.orcam.me.uk> Date: Wed, 14 Dec 2011 02:58:03 +0000 From: Maciej W. Rozycki <ma...@codesourcery.com> To: gcc-patc...@gcc.gnu.org Cc: Richard Sandiford <rdsandif...@googlemail.com>, Catherine Moore <c...@codesourcery.com> Subject: [PATCH] MIPS16: Fix truncated DWARF-2 line information 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 <sinfrob16+20> and ends at 0x18 <sinfrob16+24>. (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 <sinfrob16> and ends at 0x14 <sinfrob16+20>. (gdb) info line *sinfrob16+0x15 Line 5 of "sinfrob16.c" starts at address 0x14 <sinfrob16+20> and ends at 0x18 <sinfrob16+24>. (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 <ma...@codesourcery.com> 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)); }