diff mbox

MIPS16: Fix truncated DWARF-2 line information

Message ID alpine.DEB.1.10.1112132001040.5354@tp.orcam.me.uk
State New
Headers show

Commit Message

Maciej W. Rozycki Dec. 14, 2011, 2:58 a.m. UTC
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  <macro@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

Comments

Richard Sandiford Dec. 14, 2011, 7:11 p.m. UTC | #1
"Maciej W. Rozycki" <macro@codesourcery.com> writes:
>  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).

I think I'd prefer to change where the thunc is emitted.  We shouldn't
really have the thunk coming between the MIPS16 code and its .cfi_startproc
either.  And the thunk should probably have CFI info itself.

I'll try to look at it sometime if you don't beat me to it.

>  Regression-testing this change turned out to be quite tricky as current 
> trunk does not appear to build for the mips-sde-elf target:

Gah.  mipsisa64-elfoabi is another option FWIW.

> and the mips-linux-gnu configuration is not ready yet for MIPS16 testing.

Out of interest, what goes wrong?  I've been testing -mabi=32/-mips16 on
mips64-linux-gnu for some time without difficulty.

Anyway, whatever does end up going in to trunk really does need to be
tested against trunk first.

Richard
Maciej W. Rozycki May 8, 2012, 8:38 a.m. UTC | #2
Hi Richard,

 Resurrecting the issue now that I have new data.

On Wed, 14 Dec 2011, Richard Sandiford wrote:

> >  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).
> 
> I think I'd prefer to change where the thunc is emitted.  We shouldn't
> really have the thunk coming between the MIPS16 code and its .cfi_startproc
> either.  And the thunk should probably have CFI info itself.
> 
> I'll try to look at it sometime if you don't beat me to it.

 OK, whatever you prefer.  I hope that CFI data won't confuse GDB, any 
thunks should really be skipped over in regular debugging (i.e. unless you 
single-step by the machine instruction).

> >  Regression-testing this change turned out to be quite tricky as current 
> > trunk does not appear to build for the mips-sde-elf target:
> 
> Gah.  mipsisa64-elfoabi is another option FWIW.

 I'm not sure if that's a configuration I could test without tremendous 
effort.  Thanks for fixing mips-sde-elf support though.

> > and the mips-linux-gnu configuration is not ready yet for MIPS16 testing.
> 
> Out of interest, what goes wrong?  I've been testing -mabi=32/-mips16 on
> mips64-linux-gnu for some time without difficulty.

 I've thought some pieces are missing upstream, but perhaps I've been 
confused.  I reckon there was a nasty issue with GCC confusing the symbols 
used (using the wrong symbol alias or failing to use one) in the context 
of using MIPS16 thunks and PLT (that we discovered as soon as or shortly 
after we started using such a setup, so that wasn't anything particularly 
obscure), but perhaps the fix for that issue has been actually submitted 
and included upstream already.

 Are you using a hard-float multilib for your -mabi=32/-mips16 Linux 
testing?

> Anyway, whatever does end up going in to trunk really does need to be
> tested against trunk first.

 I did that testing now, and filed PR target/53276 so that this issue 
isn't lost.  I'll continue using the fix I proposed until you have 
implemented your suggestions; it's unlikely I'll be able to find an extra 
time slot to look into it any further given that I have a working solution 
and lots of other issues to deal with.  I can't guarantee I'll keep that 
promise though. ;)

 I have some small improvements to how some of these thunks are generated 
outstanding; I'll try to push them through testing and offer them to you 
as time permits now that I've got a reliable configuration for upstream 
GCC testing.

  Maciej
Richard Sandiford May 8, 2012, 5:43 p.m. UTC | #3
"Maciej W. Rozycki" <macro@codesourcery.com> writes:
>> > and the mips-linux-gnu configuration is not ready yet for MIPS16 testing.
>> 
>> Out of interest, what goes wrong?  I've been testing -mabi=32/-mips16 on
>> mips64-linux-gnu for some time without difficulty.
>
>  I've thought some pieces are missing upstream, but perhaps I've been 
> confused.  I reckon there was a nasty issue with GCC confusing the symbols 
> used (using the wrong symbol alias or failing to use one) in the context 
> of using MIPS16 thunks and PLT (that we discovered as soon as or shortly 
> after we started using such a setup, so that wasn't anything particularly 
> obscure), but perhaps the fix for that issue has been actually submitted 
> and included upstream already.
>
>  Are you using a hard-float multilib for your -mabi=32/-mips16 Linux 
> testing?

Yeah.  As an example:

   http://gcc.gnu.org/ml/gcc-testresults/2012-03/msg00393.html

which doesn't look to bad.  Clean fortran results, which I expect
would test the FP interworking fairly heavily.  (It's certainly
been a source of bug fixes in the past, although I don't remember
the results ever being terrible.)

FAOD, this is with normal MIPS libraries and mips16 executables.
There's still no way of building mips16 multilibs out of the box.

Richard
Maciej W. Rozycki May 9, 2012, 6:17 a.m. UTC | #4
On Tue, 8 May 2012, Richard Sandiford wrote:

> >  Are you using a hard-float multilib for your -mabi=32/-mips16 Linux 
> > testing?
> 
> Yeah.  As an example:
> 
>    http://gcc.gnu.org/ml/gcc-testresults/2012-03/msg00393.html
> 
> which doesn't look to bad.  Clean fortran results, which I expect
> would test the FP interworking fairly heavily.  (It's certainly
> been a source of bug fixes in the past, although I don't remember
> the results ever being terrible.)

 Yes, these look very good indeed.  Especially with QEMU that I do not 
feel terribly confident about as far as MIPS16 emulation is concerned (I 
still need to track down a single piece of real silicon supporting both 
MIPS64 and MIPS16 code at a time).

> FAOD, this is with normal MIPS libraries and mips16 executables.
> There's still no way of building mips16 multilibs out of the box.

 I've checked some notes and the issue was with MIPS16 FP PIC code (and 
therefore obviously SVR4 stubs rather than PLT) indeed.  I hope these 
pieces will get submitted eventually.

  Maciej
diff mbox

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