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 <write_tree+2144>: ld [ %i5 + 0x1c ], %o2 0x00013e44 <write_tree+2148>: sethi %hi(0x1e800), %o0 0x00013e48 <write_tree+2152>: or %l1, 0x110, %o1 0x00013e4c <write_tree+2156>: call 0x3510c <printf@plt> 0x00013e50 <write_tree+2160>: or %o0, 0x258, %o0 0x00013e54 <write_tree+2164>: b %xcc, 0x13bf4 <write_tree+1556> 0x00013e58 <write_tree+2168>: ld [ %i0 ], %i5 0x00013e5c <write_tree+2172>: be,pn %icc, 0x13850 <write_tree+624> => 0x00013e60 <write_tree+2176>: sethi %hi(0x1f400), %i3 0x00013e64 <write_tree+2180>: sethi %hi(0x1e800), %o0 0x00013e68 <write_tree+2184>: or %o0, 0x2b0, %o0 ! 0x1eab0 0x00013e6c <write_tree+2188>: call 0x3510c <printf@plt> 0x00013e70 <write_tree+2192>: or %i3, 0xe8, %o1 0x00013e74 <write_tree+2196>: cmp %l7, 7 0x00013e78 <write_tree+2200>: sll %l7, 2, %g1 0x00013e7c <write_tree+2204>: sethi %hi(0x1e800), %o0 0x00013e80 <write_tree+2208>: mov %l6, %o1 0x00013e84 <write_tree+2212>: call 0x3510c <printf@plt> 0x00013e88 <write_tree+2216>: or %o0, 0x3e8, %o0 0x00013e8c <write_tree+2220>: b %xcc, 0x13bac <write_tree+1484> 0x00013e90 <write_tree+2224>: ld [ %fp + -192 ], %g3 0x00013e94 <write_tree+2228>: b %xcc, 0x13ad0 <write_tree+1264> 0x00013e98 <write_tree+2232>: st %g2, [ %fp + -188 ] 0x00013e9c <write_tree+2236>: 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-gcc-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: http://lists.debian.org/20111113123124.ga4...@wooyd.org