This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Fix another case of duplicate .loc directives
- From: Daniel Jacobowitz <drow at false dot org>
- To: binutils at sourceware dot org
- Date: Wed, 29 Aug 2007 16:03:52 -0400
- Subject: Fix another case of duplicate .loc directives
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...