This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[PATCH] Bad DWARF2 line information for MIPS16
- From: "Maciej W. Rozycki" <macro at mips dot com>
- To: binutils at sources dot redhat dot com
- Cc: "Maciej W. Rozycki" <macro at linux-mips dot org>
- Date: Mon, 21 Feb 2005 21:50:29 +0000 (GMT)
- Subject: [PATCH] Bad DWARF2 line information for MIPS16
Hello,
Investigating a problem with gdb setting up breakpoints in a middle of
MIPS16 extended instructions I've discovered incorrect DWARF2 line
information is output for relaxed frags. The culprit is address offsets
are calculated relating to instruction ends and relaxed frags are
initially set up for standard instructions. Then when an extended
alternative is used, occupying twice as much space, the address offset
points to a middle of that instruction.
Apparently other ports have encountered similar problems in the past and
the solution is to calculate address offsets relating to instruction
beginnings. Here is a corresponding update for MIPS. I've tested it for
mips64-linux-gnu, mipsel-linux-gnu, mips64el-elf and mips64-elf with no
regressions (I've run the gdb testsuite under sim for one of our
configurations involving MIPS64 just in case as well; standard MIPS should
be unaffected by this change). I've prepared a DWARF2 test case to check
we get line information right.
gas/:
2005-02-21 Maciej W. Rozycki <macro@mips.com>
* config/tc-mips.c (append_insn): Call dwarf2_emit_insn() before
emitting insn.
gas/testsuite/:
2005-02-21 Maciej W. Rozycki <macro@mips.com>
* gas/mips/mips16-dwarf2.d: New test to check DWARF2 line
information for MIPS16.
* gas/mips/mips16-dwarf2.s: Source for the new test.
* gas/mips/mips.exp: Run the new test.
OK to apply?
Maciej
binutils-2.15.94-20050221-mips16-dwarf2.patch
diff -up --recursive --new-file binutils-2.15.94-20050221.macro/gas/config/tc-mips.c binutils-2.15.94-20050221/gas/config/tc-mips.c
--- binutils-2.15.94-20050221.macro/gas/config/tc-mips.c 2005-02-21 17:55:54.000000000 +0000
+++ binutils-2.15.94-20050221/gas/config/tc-mips.c 2005-02-21 21:25:58.000000000 +0000
@@ -2009,6 +2009,15 @@ append_insn (struct mips_cl_insn *ip, ex
}
}
+#ifdef OBJ_ELF
+ /* The value passed to dwarf2_emit_insn is the distance between
+ the beginning of the current instruction and the address that
+ should be recorded in the debug tables. For MIPS16 debug info
+ we want to use ISA-encoded addresses, so we pass -1 for an
+ address higher by one than the current. */
+ dwarf2_emit_insn (mips_opts.mips16 ? -1 : 0);
+#endif
+
/* Record the frag type before frag_var. */
if (prev_insn_frag)
prev_insn_frag_type = prev_insn_frag->fr_type;
@@ -2243,24 +2252,11 @@ append_insn (struct mips_cl_insn *ip, ex
}
if (! mips_opts.mips16)
- {
md_number_to_chars (f, ip->insn_opcode, 4);
-#ifdef OBJ_ELF
- dwarf2_emit_insn (4);
-#endif
- }
else if (*reloc_type == BFD_RELOC_MIPS16_JMP)
{
md_number_to_chars (f, ip->insn_opcode >> 16, 2);
md_number_to_chars (f + 2, ip->insn_opcode & 0xffff, 2);
-#ifdef OBJ_ELF
- /* The value passed to dwarf2_emit_insn is the distance between
- the end of the current instruction and the address that should
- be recorded in the debug tables. Since we want to use ISA-encoded
- addresses in MIPS16 debug info, the value is one byte less than
- the real instruction length. */
- dwarf2_emit_insn (3);
-#endif
}
else
{
@@ -2270,9 +2266,6 @@ append_insn (struct mips_cl_insn *ip, ex
f += 2;
}
md_number_to_chars (f, ip->insn_opcode, 2);
-#ifdef OBJ_ELF
- dwarf2_emit_insn (ip->use_extend ? 3 : 1);
-#endif
}
/* Update the register mask information. */
diff -up --recursive --new-file binutils-2.15.94-20050221.macro/gas/testsuite/gas/mips/mips.exp binutils-2.15.94-20050221/gas/testsuite/gas/mips/mips.exp
--- binutils-2.15.94-20050221.macro/gas/testsuite/gas/mips/mips.exp 2005-02-21 17:55:58.000000000 +0000
+++ binutils-2.15.94-20050221/gas/testsuite/gas/mips/mips.exp 2005-02-21 21:26:36.000000000 +0000
@@ -746,4 +746,8 @@ if { [istarget mips*-*-*] } then {
run_list_test "noat-5" ""
run_list_test "noat-6" ""
run_list_test "noat-7" ""
+
+ if { $elf && !$no_mips16 } {
+ run_dump_test "mips16-dwarf2"
+ }
}
diff -up --recursive --new-file binutils-2.15.94-20050221.macro/gas/testsuite/gas/mips/mips16-dwarf2.d binutils-2.15.94-20050221/gas/testsuite/gas/mips/mips16-dwarf2.d
--- binutils-2.15.94-20050221.macro/gas/testsuite/gas/mips/mips16-dwarf2.d 1970-01-01 00:00:00.000000000 +0000
+++ binutils-2.15.94-20050221/gas/testsuite/gas/mips/mips16-dwarf2.d 2005-02-21 21:01:56.000000000 +0000
@@ -0,0 +1,47 @@
+#readelf: -wl
+#name: MIPS16 DWARF2
+#as: -mips16 -no-mdebug -g0
+#source: mips16-dwarf2.s
+
+Dump of debug contents of section \.debug_line:
+
+ Length: 64
+ DWARF Version: 2
+ Prologue Length: 35
+ Minimum Instruction Length: 1
+ Initial value of 'is_stmt': 1
+ Line Base: -5
+ Line Range: 14
+ Opcode Base: 10
+ \(Pointer size: 4\)
+
+ 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
+
+ The Directory Table is empty\.
+
+ The File Name Table:
+ Entry Dir Time Size Name
+ 1 0 0 0 mips16-dwarf2\.s
+
+ Line Number Statements:
+ Extended opcode 2: set Address to 0x1
+ Special opcode 5: advance Address by 0 to 0x1 and Line by 0 to 1
+ Special opcode 34: advance Address by 2 to 0x3 and Line by 1 to 2
+ Special opcode 34: advance Address by 2 to 0x5 and Line by 1 to 3
+ Special opcode 62: advance Address by 4 to 0x9 and Line by 1 to 4
+ Special opcode 34: advance Address by 2 to 0xb and Line by 1 to 5
+ Special opcode 62: advance Address by 4 to 0xf and Line by 1 to 6
+ Special opcode 62: advance Address by 4 to 0x13 and Line by 1 to 7
+ Advance PC by 2286 to 901
+ Special opcode 6: advance Address by 0 to 0x901 and Line by 1 to 8
+ Advance PC by 15 to 910
+ Extended opcode 1: End of Sequence
diff -up --recursive --new-file binutils-2.15.94-20050221.macro/gas/testsuite/gas/mips/mips16-dwarf2.s binutils-2.15.94-20050221/gas/testsuite/gas/mips/mips16-dwarf2.s
--- binutils-2.15.94-20050221.macro/gas/testsuite/gas/mips/mips16-dwarf2.s 1970-01-01 00:00:00.000000000 +0000
+++ binutils-2.15.94-20050221/gas/testsuite/gas/mips/mips16-dwarf2.s 2005-02-21 21:19:29.000000000 +0000
@@ -0,0 +1,66 @@
+# Source file used to test DWARF2 information for MIPS16.
+
+ .set mips16
+
+ .text
+.Ltext0:
+ .p2align 2
+
+ .file 1 "mips16-dwarf2.s"
+stuff:
+ .loc 1 1 0
+ nop
+ .loc 1 2 0
+ li $2, 0
+ .loc 1 3 0
+ li $2, 0x1234
+ .loc 1 4 0
+ lw $2, 0f
+ .loc 1 5 0
+ lw $2, 1f
+ .loc 1 6 0
+ b 0f
+ nop
+ .loc 1 7 0
+ b 1f
+ nop
+ .loc 1 8 0
+
+ .p2align 8
+0:
+ .space 2048
+1:
+ nop
+# align section end to 16-byte boundary for easier testing on multiple targets
+ .p2align 4
+.Letext0:
+
+ .section .debug_info,"",@progbits
+.Ldebug_info0:
+ .4byte .Ledebug_info0 - .L1debug_info0 # length
+.L1debug_info0:
+ .2byte 2 # version
+ .4byte .Ldebug_abbrev0 # abbrev offset
+ .byte 4 # address size
+ .uleb128 1 # abbrev code
+ .4byte .Ldebug_line0 # DW_AT_stmt_list
+ .4byte .Ltext0 # DW_AT_low_pc
+ .4byte .Letext0 # DW_AT_high_pc
+.Ledebug_info0:
+
+ .section .debug_abbrev,"",@progbits
+.Ldebug_abbrev0:
+ .uleb128 0x1 # abbrev code
+ .uleb128 0x11 # DW_TAG_compile_unit
+ .byte 0x0 # DW_CHILDREN_no
+ .uleb128 0x10 # DW_AT_stmt_list
+ .uleb128 0x6 # DW_FORM_data4
+ .uleb128 0x11 # DW_AT_low_pc
+ .uleb128 0x1 # DW_FORM_addr
+ .uleb128 0x12 # DW_AT_high_pc
+ .uleb128 0x1 # DW_FORM_addr
+ .byte 0x0
+ .byte 0x0
+
+ .section .debug_line,"",@progbits
+.Ldebug_line0: