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));
 }

Reply via email to