Fix another case of duplicate .loc directives

Daniel Jacobowitz drow@false.org
Wed Aug 29 21:30:00 GMT 2007


Quoting from http://sourceware.org/ml/binutils/2002-04/msg00203.html:

> GDB uses duplicate line numbers to detect the end of the prologue.
> GCC would carefully emit them... and gas was stripping them out.

Geoff's revised patch was checked in and is still there.  That fixed
the case of two .loc directives at different PCs but using the same
line number.  I found today a second sort of "duplication".  A
powerpc-linux compiler turns this:

int x, y;
void marker (void)
{
  x += y;
}

Into this:

        .align 2
        .globl marker
        .type   marker, @function
marker:
.LFB2:
        .file 1 "marker.c"
        .loc 1 3 0
        .loc 1 4 0
        lis 10,x@ha
        lis 9,y@ha
        lwz 11,x@l(10)
        lwz 0,y@l(9)
        add 0,0,11
        stw 0,x@l(10)
        .loc 1 5 0
        blr

This function doesn't need a prologue and the prologue has been
optimized completely away.  But GDB needs the duplicated .loc for the
same reason as before; otherwise we will assume that line 4 is the
prologue and break only on line 5.

I've committed the attached patch.  It causes no regressions in the
binutils testsuite on powerpc-eabisim, and has no effect on the
GDB testsuite (which so far only contains unoptimized code - but
I'm working on that).

-- 
Daniel Jacobowitz
CodeSourcery

2007-08-29  Daniel Jacobowitz  <dan@codesourcery.com>

	* dwarf2dbg.c (dwarf2_directive_loc): Emit duplicate .loc directives.

	* gas/lns/lns-duplicate.d, gas/lns/lns-duplicate.s: New.
	* gas/lns/lns.exp: Run lns-duplicate.

Index: dwarf2dbg.c
===================================================================
RCS file: /scratch/gcc/repos/src/src/gas/dwarf2dbg.c,v
retrieving revision 1.90
diff -u -p -r1.90 dwarf2dbg.c
--- dwarf2dbg.c	24 Aug 2007 21:49:55 -0000	1.90
+++ dwarf2dbg.c	29 Aug 2007 19:39:32 -0000
@@ -570,6 +570,11 @@ dwarf2_directive_loc (int dummy ATTRIBUT
 {
   offsetT filenum, line;
 
+  /* If we see two .loc directives in a row, force the first one to be
+     output now.  */
+  if (loc_directive_seen)
+    dwarf2_emit_insn (0);
+
   filenum = get_absolute_expression ();
   SKIP_WHITESPACE ();
   line = get_absolute_expression ();
Index: testsuite/gas/lns/lns-duplicate.d
===================================================================
RCS file: testsuite/gas/lns/lns-duplicate.d
diff -N testsuite/gas/lns/lns-duplicate.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/lns/lns-duplicate.d	29 Aug 2007 19:49:23 -0000
@@ -0,0 +1,10 @@
+#readelf: -wl
+#name: lns-duplicate
+Dump of debug contents of section \.debug_line:
+#...
+ Line Number Statements:
+  Extended opcode 2: set Address to .*
+  Copy
+  Set basic block
+  .* by 1 to 2
+#pass
Index: testsuite/gas/lns/lns-duplicate.s
===================================================================
RCS file: testsuite/gas/lns/lns-duplicate.s
diff -N testsuite/gas/lns/lns-duplicate.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gas/lns/lns-duplicate.s	29 Aug 2007 19:51:18 -0000
@@ -0,0 +1,5 @@
+	.loc_mark_labels 1
+	.file 1 "foo.s"
+	.loc 1 1 0
+	.loc 1 2 0
+.Llabel:
Index: testsuite/gas/lns/lns.exp
===================================================================
RCS file: /scratch/gcc/repos/src/src/gas/testsuite/gas/lns/lns.exp,v
retrieving revision 1.6
diff -u -p -r1.6 lns.exp
--- testsuite/gas/lns/lns.exp	5 Jun 2007 17:00:32 -0000	1.6
+++ testsuite/gas/lns/lns.exp	29 Aug 2007 19:49:51 -0000
@@ -4,6 +4,8 @@ if ![is_elf_format] then {
 
 run_list_test "lns-diag-1" ""
 
+run_dump_test "lns-duplicate"
+
 # ??? Won't work on targets that don't have a bare "nop" insn.
 # Perhaps we could arrange for an include file or something that
 # defined a macro...



More information about the Binutils mailing list