reassign 648016 gcc-4.6
found 648016 4.6.2-4
thanks
This bug really is in gcc-4.6, because it is currently the default sid
gcc and it is used to (mis)compile src/build/genrecog.c during
gcc-avr build, which later crashes. I'm fairly certain that this is
gcc problem, because if the binary is compiled with -O0, the problem
goes away. All debugging output below was obtained on a sparc machine
running up-to-date sid, invoking build/genrecog under gdb with a
single argument of '../../src/gcc/config/avr/avr.md'.
Tracing the execution is somewhat tricky, since failure happens within
write_tree(), and most of the functions write_tree() calls
(write_tree_1, write_switch, write_node, write_action, etc) are
optimized out. The output generated by
build/genrecog ../../src/gcc/config/avr/avr.md
is the same as the one produced on an amd64 system until we hit the
following code in genrecog.c/write_switch():
else if (type == DT_mode
|| type == DT_veclen
|| type == DT_elt_zero_int
|| type == DT_elt_one_int
|| type == DT_elt_zero_wide_safe)
{
const char *indent = "";
/* We cast switch parameter to integer, so we must ensure that the value
fits. */
if (type == DT_elt_zero_wide_safe)
{
indent = " ";
printf(" if ((int) XWINT (x%d, 0) == XWINT (x%d, 0))\n", depth, depth);
}
printf ("%s switch (", indent);
switch (type)
{
case DT_mode:
printf ("GET_MODE (x%d)", depth);
break;
case DT_veclen:
printf ("XVECLEN (x%d, 0)", depth);
break;
case DT_elt_zero_int:
printf ("XINT (x%d, 0)", depth);
break;
case DT_elt_one_int:
printf ("XINT (x%d, 1)", depth);
break;
case DT_elt_zero_wide_safe:
/* Convert result of XWINT to int for portability since some C
compilers won't do it and some will. */
printf ("(int) XWINT (x%d, 0)", depth);
break;
default:
gcc_unreachable ();
}
The problem appears after executing the
printf ("%s switch (", indent);
statetement. It looks like compiler generates a number of small stubs
within write_tree() for calling printf with all possible format
statements. Here's how the generated assembler code looks for this
particular one, starting at 0x00013e60:
Dump of assembler code from 0x13e40 to 0x13ea0:
0x00013e40 :ld [ %i5 + 0x1c ], %o2
0x00013e44 :sethi %hi(0x1e800), %o0
0x00013e48 :or %l1, 0x110, %o1
0x00013e4c :call 0x3510c
0x00013e50 :or %o0, 0x258, %o0
0x00013e54 :b %xcc, 0x13bf4
0x00013e58 :ld [ %i0 ], %i5
0x00013e5c :be,pn %icc, 0x13850
=> 0x00013e60 :sethi %hi(0x1f400), %i3
0x00013e64 :sethi %hi(0x1e800), %o0
0x00013e68 :or %o0, 0x2b0, %o0 ! 0x1eab0
0x00013e6c :call 0x3510c
0x00013e70 :or %i3, 0xe8, %o1
0x00013e74 :cmp %l7, 7
0x00013e78 :sll %l7, 2, %g1
0x00013e7c :sethi %hi(0x1e800), %o0
0x00013e80 :mov %l6, %o1
0x00013e84 :call 0x3510c
0x00013e88 :or %o0, 0x3e8, %o0
0x00013e8c :b %xcc, 0x13bac
0x00013e90 :ld [ %fp + -192 ], %g3
0x00013e94 :b %xcc, 0x13ad0
0x00013e98 :st %g2, [ %fp + -188 ]
0x00013e9c :cmp %g0, %i3
End of assembler dump.
Confirmation that 0x1eab0 contains the correct format statement
(passed to printf in %o0):
(gdb) printf "%s\n", (char *) 0x1eab0
%s switch (
(gdb)
A remarkable feature of this stub is that it does not have a return
branch statement, like others do (see 0x00013e54, for example). So,
instead of returning to the correct location where the stub was
invoked in write_switch(), we fall through to 0x00013e74, and start
executing the next stub, which invokes printf with a format
statement at 0x1ebe8 (== 0x1e800 | 0x3e8):
(gdb) printf "%s\n", (char *) 0x1ebe8
%sreturn gen_split_%d (insn, operands);
(gdb)
This is completely unrelated code, normally invoked by
write_action(), line 2182. Once it's done, we jump back to completely
wrong location at 0x00013e8c, eventually causing a crash.
Best regards,
--
Jurij Smakov ju...@wooyd.org
Key: http://www.wooyd.org/pgpkey/ KeyID: C99E03CC
--
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org