[Pkg-samba-maint] Bug#445566: compiler bug pin-down
Herbert Valerio Riedel
hvr at gnu.org
Mon Dec 31 09:33:43 UTC 2007
hello!
I did some investigation, and the compiler bug seems to be related to
code inlining; I pinned it down to the following code:
/***********************************************************************/
typedef unsigned short u16;
typedef unsigned char u8;
static void
do_segfault(u8 in_buf[], const u8 out_buf[], const int len)
{
int i;
for (i = 0; i < len; i++) {
//SSVAL(in_buf, 2*i, SVAL(out_buf,2*i)); // more or less just a byte-wise memcpy
asm("nop\n");
in_buf[2*i] = ( out_buf[2*i] | out_buf[(2*i)+1]<<8 ) & 0xFF; // in_buf[2*i] = out_buf[2*i];
asm("nop\n");
in_buf[(2*i)+1] = ( out_buf[2*i] | out_buf[(2*i)+1]<<8 ) >> 8; // in_buf[(2*i)+1] = out_buf[(2*i)+1];
asm("nop\n");
}
}
int main(int argc, char *argv[])
{
u8 outbuf[32] = "buffer ";
u8 inbuf[32] = "\f";
asm("nop\n");
do_segfault(inbuf, outbuf, 12);
asm("nop\n");
return 0;
}
/***********************************************************************/
which when compiled with 4.2.3 20071123 (prerelease) (Debian 4.2.2-4),
causes a segfault when using -O2, but works when either removing the
'static' modifier and thus avoiding inlining of do_segfault, or by using
an optimization level which does avoid that...
the generated assembler code is quite broken for the optimized case:
(I've only pasted and commented the relevant section containing the 5
nops)
// r4 points to outbuf (= source buffer)
// sp points to inbuf (= target buffer)
#APP
nop
mov r2, sp
add r1, sp, #56 // upper loop-bound; should have been #12
.L2:
#APP
nop
ldrb r3, [r4, #0]
strb r3, [r2, #0]
#APP
nop
ldrb r3, [r4, #1]
strb r3, [r2, #1]
#APP
nop
cmp r4, r1 // upper loop-bound check
add r2, r2, #2 // increment target buffer (NB: source buffer is not incremented!)
bne .L2 // repeat loop if upper loop-bound not reached yet
#APP
nop
cheers,
hvr
More information about the Pkg-samba-maint
mailing list