This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]