Codegen bug in current CVS on x86
Zack Weinberg
zack@rabi.columbia.edu
Wed Feb 10 07:32:00 GMT 1999
The present CVS tree miscompiles glibc's strncpy.c, such that under
some conditions it will segfault when handed perfectly well-formed
arguments. I've been unable to come up with a self-contained
testcase, but this reliably happens when strncpy is used by the
`rpcgen' program as part of the libc build.
I've attached the C source for strncpy.c and the assembly output for
egcs 1.1.1 and the current snapshot (-O2 -mpentium). I think the
problem is that the source pointer sometimes gets initialized to
garbage, but I get lost in all those pointless flushes to memory...
zw
#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1999-02-10 10:21 EST by <zack@midnite>.
# Source directory was `/usr/home/zack/t'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 798 -rw-r--r-- strncpy.c
# 1645 -rw-r--r-- strncpy.s
# 1329 -rw-r--r-- strncpy.s.111
#
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
if test "$gettext_dir" = FAILED && test -f $dir/gettext \
&& ($dir/gettext --version >/dev/null 2>&1)
then
set `$dir/gettext --version 2>&1`
if test "$3" = GNU
then
gettext_dir=$dir
fi
fi
if test "$locale_dir" = FAILED && test -f $dir/shar \
&& ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
then
locale_dir=`$dir/shar --print-text-domain-dir`
fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
echo=echo
else
TEXTDOMAINDIR=$locale_dir
export TEXTDOMAINDIR
TEXTDOMAIN=sharutils
export TEXTDOMAIN
echo="$gettext_dir/gettext -s"
fi
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
shar_touch=touch
else
shar_touch=:
echo
$echo 'WARNING: not restoring timestamps. Consider getting and'
$echo "installing GNU \`touch', distributed in GNU File Utilities..."
echo
fi
rm -f 1231235999 $$.touch
#
if mkdir _sh15926; then
$echo 'x -' 'creating lock directory'
else
$echo 'failed to create lock directory'
exit 1
fi
# ============= strncpy.c ==============
if test -f 'strncpy.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'strncpy.c' '(file already exists)'
else
$echo 'x -' extracting 'strncpy.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'strncpy.c' &&
typedef unsigned long size_t;
X
char *
strncpy (s1, s2, n)
X char *s1;
X const char *s2;
X size_t n;
{
X char c;
X char *s = s1;
X
X --s1;
X
X if (n >= 4)
X {
X size_t n4 = n >> 2;
X
X for (;;)
X {
X c = *s2++;
X *++s1 = c;
X if (c == '\0')
X break;
X c = *s2++;
X *++s1 = c;
X if (c == '\0')
X break;
X c = *s2++;
X *++s1 = c;
X if (c == '\0')
X break;
X c = *s2++;
X *++s1 = c;
X if (c == '\0')
X break;
X if (--n4 == 0)
X goto last_chars;
X }
X n = n - (s1 - s) - 1;
X if (n == 0)
X return s;
X goto zero_fill;
X }
X
X last_chars:
X n &= 3;
X if (n == 0)
X return s;
X
X do
X {
X c = *s2++;
X *++s1 = c;
X if (--n == 0)
X return s;
X }
X while (c != '\0');
X
X zero_fill:
X do
X *++s1 = '\0';
X while (--n > 0);
X
X return s;
}
SHAR_EOF
$shar_touch -am 021010201999 'strncpy.c' &&
chmod 0644 'strncpy.c' ||
$echo 'restore of' 'strncpy.c' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'strncpy.c:' 'MD5 check failed'
35197ca4801e7b3a40dad4f2e289252d strncpy.c
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'strncpy.c'`"
test 798 -eq "$shar_count" ||
$echo 'strncpy.c:' 'original size' '798,' 'current size' "$shar_count!"
fi
fi
# ============= strncpy.s ==============
if test -f 'strncpy.s' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'strncpy.s' '(file already exists)'
else
$echo 'x -' extracting 'strncpy.s' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'strncpy.s' &&
X .file "strncpy.c"
X .version "01.01"
gcc2_compiled.:
X.text
X .align 4
X.globl strncpy
X .type strncpy,@function
strncpy:
X pushl %ebp
X movl %esp,%ebp
X subl $28,%esp
X pushl %edi
X pushl %esi
X pushl %ebx
X movl 12(%ebp),%ecx
X movl 16(%ebp),%edx
X movl 8(%ebp),%eax
X movl %eax,-4(%ebp)
X movl %eax,%ebx
X decl %ebx
X cmpl $3,%edx
X jbe .L12
X movl %edx,-8(%ebp)
X shrl $2,-8(%ebp)
X leal 2(%ecx),%esi
X movl %esi,-20(%ebp)
X movl %eax,%edi
X jmp .L4
X .p2align 4,,7
X.L10:
X movl %edi,-28(%ebp)
X leal 1(%ecx),%eax
X movl %eax,-24(%ebp)
X leal 3(%ecx),%esi
X movl %esi,-16(%ebp)
X decl -8(%ebp)
X jz .L12
X.L4:
X movl -16(%ebp),%esi
X movb -3(%esi),%al
X movl -28(%ebp),%esi
X movb %al,(%esi)
X testb %al,%al
X je .L5
X movl -24(%ebp),%esi
X movb (%esi),%al
X movl -28(%ebp),%esi
X incl %esi
X movl %esi,-12(%ebp)
X movl -28(%ebp),%esi
X movb %al,1(%esi)
X testb %al,%al
X je .L5
X movl -20(%ebp),%esi
X movb (%esi),%al
X movb %al,2(%edi)
X testb %al,%al
X je .L5
X movl -16(%ebp),%esi
X addl $4,%ecx
X addl $4,%edi
X addl $4,%ebx
X movb (%esi),%al
X movl -12(%ebp),%esi
X addl $4,-20(%ebp)
X movb %al,-2(%esi)
X testb %al,%al
X jne .L10
X.L5:
X movl %ebx,%eax
X subl -4(%ebp),%eax
X subl %eax,%edx
X movl %edx,%eax
X leal -1(%eax),%edx
X testl %edx,%edx
X jne .L23
X jmp .L30
X .p2align 4,,7
X.L12:
X andl $3,%edx
X je .L30
X .p2align 4,,7
X.L17:
X movb (%ecx),%al
X incl %ecx
X incl %ebx
X movb %al,(%ebx)
X decl %edx
X jz .L30
X testb %al,%al
X jne .L17
X .p2align 4,,7
X.L23:
X incl %ebx
X movb $0,(%ebx)
X decl %edx
X jnz .L23
X.L30:
X movl -4(%ebp),%eax
X popl %ebx
X popl %esi
X popl %edi
X movl %ebp,%esp
X popl %ebp
X ret
X.Lfe1:
X .size strncpy,.Lfe1-strncpy
X .ident "GCC: (GNU) egcs-2.93.06 19990209 (gcc2 ss-980929 experimental)"
SHAR_EOF
$shar_touch -am 021009531999 'strncpy.s' &&
chmod 0644 'strncpy.s' ||
$echo 'restore of' 'strncpy.s' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'strncpy.s:' 'MD5 check failed'
2b8d4aa60b2ef1bb5614cf09a1cd12b4 strncpy.s
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'strncpy.s'`"
test 1645 -eq "$shar_count" ||
$echo 'strncpy.s:' 'original size' '1645,' 'current size' "$shar_count!"
fi
fi
# ============= strncpy.s.111 ==============
if test -f 'strncpy.s.111' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'strncpy.s.111' '(file already exists)'
else
$echo 'x -' extracting 'strncpy.s.111' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'strncpy.s.111' &&
X .file "strncpy.c"
X .version "01.01"
gcc2_compiled.:
X.text
X .align 4
X.globl strncpy
X .type strncpy,@function
strncpy:
X pushl %ebp
X movl %esp,%ebp
X pushl %edi
X pushl %esi
X pushl %ebx
X movl 8(%ebp),%edi
X movl 12(%ebp),%edx
X movl 16(%ebp),%ebx
X leal -1(%edi),%ecx
X cmpl $3,%ebx
X jbe .L11
X movb (%edx),%al
X movl %ebx,%esi
X incl %edx
X shrl $2,%esi
X movl %edi,%ecx
X movb %al,(%edi)
X testb %al,%al
X je .L4
X .p2align 4,,7
X.L6:
X incl %ecx
X movb (%edx),%al
X incl %edx
X movb %al,(%ecx)
X testb %al,%al
X je .L4
X incl %ecx
X movb (%edx),%al
X incl %edx
X movb %al,(%ecx)
X testb %al,%al
X je .L4
X incl %ecx
X movb (%edx),%al
X incl %edx
X movb %al,(%ecx)
X testb %al,%al
X je .L4
X decl %esi
X jz .L11
X incl %ecx
X movb (%edx),%al
X incl %edx
X movb %al,(%ecx)
X testb %al,%al
X jne .L6
X.L4:
X movl %ecx,%eax
X subl %edi,%eax
X subl %eax,%ebx
X movl %ebx,%eax
X leal -1(%eax),%ebx
X testl %ebx,%ebx
X jne .L22
X jmp .L29
X .p2align 4,,7
X.L11:
X andl $3,%ebx
X je .L29
X .p2align 4,,7
X.L16:
X incl %ecx
X movb (%edx),%al
X incl %edx
X movb %al,(%ecx)
X decl %ebx
X jz .L29
X testb %al,%al
X jne .L16
X .p2align 4,,7
X.L22:
X incl %ecx
X movb $0,(%ecx)
X decl %ebx
X jnz .L22
X.L29:
X movl %edi,%eax
X leal -12(%ebp),%esp
X popl %ebx
X popl %esi
X popl %edi
X movl %ebp,%esp
X popl %ebp
X ret
X.Lfe1:
X .size strncpy,.Lfe1-strncpy
X .ident "GCC: (GNU) egcs-2.91.60 Debian 2.1 (egcs-1.1.1 release)"
SHAR_EOF
$shar_touch -am 021009541999 'strncpy.s.111' &&
chmod 0644 'strncpy.s.111' ||
$echo 'restore of' 'strncpy.s.111' 'failed'
if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
&& ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
md5sum -c << SHAR_EOF >/dev/null 2>&1 \
|| $echo 'strncpy.s.111:' 'MD5 check failed'
941666b71d19bd877169afb1994f8478 strncpy.s.111
SHAR_EOF
else
shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'strncpy.s.111'`"
test 1329 -eq "$shar_count" ||
$echo 'strncpy.s.111:' 'original size' '1329,' 'current size' "$shar_count!"
fi
fi
rm -fr _sh15926
exit 0
More information about the Gcc-bugs
mailing list