This is the mail archive of the 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]

mn10300 assembler relaxation breaks dwarf2 debugging info

The assembler manages to mess up the addresses of regions associated
with source lines when doing relaxations.  The problem is that we
anchor debugging info to the end of an insn minus its size.  However,
when relaxation modifies the size of the insn, debugging info isn't
adjusted.  For an example, assemble:

        .file 2 "foo"
        .loc 2 1 0
        .loc 2 2 0
        call _foo,[],0

And notice, with readelf -w, that the address of the line increment is
not the beginning of the call insn, but two addresses after it.
That's because the assembler originally assembles the insn as if call
would take just 5 bytes, assuming _foo will be no more than 64kbytes
apart, but then it realizes _foo is external, so it gets relaxes to a
32-bit offset, growing the instruction to 7 bytes, whereas the
debugging info is still anchored to the end of the insn minus 5 bytes.

The easiest fix I could find for this problem was to anchor debugging
info to the end of the frag before the relaxable insn, so that, when
the size of the relaxable frag changes, it doesn't break the debugging

I'm not 100% sure the frag_more(0) is needed before
dwarf2_emit_insn(0), and I couldn't find a case in which it would be
needed, but I thought I'd better be safe than sorry.

Ok to install?

Index: gas/ChangeLog
from  Alexandre Oliva  <>

	* config/tc-mn10300.c (md_assemble): Anchor dwarf2 line info
	before a relaxable insns.

Index: gas/config/tc-mn10300.c
RCS file: /cvs/src/src/gas/config/tc-mn10300.c,v
retrieving revision 1.24
diff -u -p -r1.24 tc-mn10300.c
--- gas/config/tc-mn10300.c 2001/05/13 23:16:30 1.24
+++ gas/config/tc-mn10300.c 2001/05/14 05:16:45
@@ -1517,6 +1517,13 @@ keep_going:
       int type;
+      /* We want to anchor the line info to the previous frag (if
+	 there isn't one, create it), so that, when the insn is
+	 resized, we still get the right address for the beginning of
+	 the region.  */
+      f = frag_more (0);
+      dwarf2_emit_insn (0);
       /* bCC  */
       if (size == 2)
@@ -1770,9 +1777,9 @@ keep_going:
 		fixP->fx_offset += offset;
-    }
-  dwarf2_emit_insn (size);
+      dwarf2_emit_insn (size);
+    }
 /* If while processing a fixup, a reloc really needs to be created

Alexandre Oliva   Enjoy Guarana', see
Red Hat GCC Developer                  aoliva@{,}
CS PhD student at IC-Unicamp        oliva@{,}
Free Software Evangelist    *Please* write to mailing lists, not to me

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