Xref: utzoo comp.unix.sysv386:9133 alt.sources:3920 Path: utzoo!utgpu!cs.utexas.edu!uunet!pdn!tscs!tct!chip From: chip@tct.com (Chip Salzenberg) Newsgroups: comp.unix.sysv386,alt.sources Subject: Bug in SCO 3.2v2 memmove(), and fix Message-ID: <285FBE64.468B@tct.com> Date: 19 Jun 91 20:28:20 GMT Organization: Teltronics/TCT, Sarasota, FL Lines: 112 SCO's memmove() function in the 3.2v2 development system libc.a library has an insidious bug: it trashes the EBX register. This register is used to hold register variables. I suspect the bug crept in due to a simple-minded translation of a '286 routine, because on the '286, BX need not be preserved. The fix is to replace memmove.o in /lib/libc.a with the version included below. Note that if you use profiling, you must also put a profiling version of memmove() in /usr/lib/libp/libc.a. To assemble the non-profiling version: as -m -o memmove.o memmove.s To assemble the profiling verson: as -m -o memmove_p.o profile.s memmove.s (How strange that this bug has gone unnoticed for so long...) #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'profile.s' <<'END_OF_FILE' X/ $Id: profile.s,v 1.1 1990/12/18 09:07:04 chip Exp $ X/ X/ Prefix file for turning on assembler profiling. X/ X Xdefine(`PROFILE',``PROFILE'') END_OF_FILE if test 139 -ne `wc -c <'profile.s'`; then echo shar: \"'profile.s'\" unpacked with wrong size! fi # end of 'profile.s' fi if test -f 'memmove.s' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'memmove.s'\" else echo shar: Extracting \"'memmove.s'\" \(687 characters\) sed "s/^X//" >'memmove.s' <<'END_OF_FILE' X/ $Id: memmove.s,v 1.3 1991/06/05 19:15:44 chip Exp $ X/ X/ Implementation of memmove(), which is inexplicably missing X/ from the SCO Unix C library. X/ X X .globl memmove Xmemmove: Xifdef(`PROFILE',` X .bss X.L1: .=.+4 X .text X mov $.L1,%edx X .globl _mcount X call _mcount X') X push %edi X push %esi X mov 12(%esp),%edi X mov 16(%esp),%esi X mov 20(%esp),%ecx X mov %edi,%eax / return value: dest X jcxz mm_exit X X mov %edi,%edx X sub %esi,%edx X jb mm_simple X cmp %edx,%ecx X jb mm_simple X X add %ecx,%edi X dec %edi X add %ecx,%esi X dec %esi X std X rep; movsb X cld X jmp mm_exit X Xmm_simple: X cld X mov %ecx,%edx X shr $2,%ecx X rep; movs X mov %edx,%ecx X and $3,%ecx X rep; movsb X Xmm_exit: X pop %esi X pop %edi X ret END_OF_FILE if test 687 -ne `wc -c <'memmove.s'`; then echo shar: \"'memmove.s'\" unpacked with wrong size! fi # end of 'memmove.s' fi echo shar: End of shell archive. exit 0