From owner-svn-src-head@freebsd.org Wed Nov 15 23:52:40 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5EEFEDEEEEC for ; Wed, 15 Nov 2017 23:52:40 +0000 (UTC) (envelope-from markmi@dsl-only.net) Received: from asp.reflexion.net (outbound-mail-210-136.reflexion.net [208.70.210.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 219A16372C for ; Wed, 15 Nov 2017 23:52:39 +0000 (UTC) (envelope-from markmi@dsl-only.net) Received: (qmail 10194 invoked from network); 15 Nov 2017 23:52:33 -0000 Received: from unknown (HELO mail-cs-02.app.dca.reflexion.local) (10.81.19.2) by 0 (rfx-qmail) with SMTP; 15 Nov 2017 23:52:33 -0000 Received: by mail-cs-02.app.dca.reflexion.local (Reflexion email security v8.40.3) with SMTP; Wed, 15 Nov 2017 18:52:33 -0500 (EST) Received: (qmail 24745 invoked from network); 15 Nov 2017 23:52:33 -0000 Received: from unknown (HELO iron2.pdx.net) (69.64.224.71) by 0 (rfx-qmail) with (AES256-SHA encrypted) SMTP; 15 Nov 2017 23:52:33 -0000 Received: from [192.168.1.25] (c-76-115-7-162.hsd1.or.comcast.net [76.115.7.162]) by iron2.pdx.net (Postfix) with ESMTPSA id F1E5CEC9518; Wed, 15 Nov 2017 15:52:32 -0800 (PST) From: Mark Millard Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Mime-Version: 1.0 (Mac OS X Mail 10.3 \(3273\)) Subject: Re: svn commit: r325765 - head/lib/libc/string Message-Id: <37F2AD18-1B69-4559-8BD3-B92E01A067BF@dsl-only.net> Date: Wed, 15 Nov 2017 15:52:32 -0800 To: Bruce Evans , svn-src-head@freebsd.org X-Mailer: Apple Mail (2.3273) X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Nov 2017 23:52:40 -0000 Bruce Evans brde at optusnet.com.au wrote on Tue Nov 14 12:41:50 UTC 2017 : > - memcpy.3. It was already documented in the BUGS section that = memcpy() is > implemented as bcopy() and therefore the "strings" "may overlap" = [then > portability considerations due to this]. This is buggier than = before: > - old bug: only the MI implementation of memcpy() clearly = implements > memcpy() as bcopy(). The amd64, i386 and arm MD implementations > do the same. head/sys/arm/arm/support.S ( -r283366 ) has 394 ENTRY(bcopy) 395 /* switch the source and destination registers */ 396 eor r0, r1, r0 397 eor r1, r0, r1 398 eor r0, r1, r0 399 EENTRY(memmove) 400 /* Do the buffers overlap? */ 401 cmp r0, r1 402 RETeq /* Bail now if src/dst are the same */ 403 subcc r3, r0, r1 /* if (dst > src) r3 =3D dst - = src */ 404 subcs r3, r1, r0 /* if (src > dsr) r3 =3D src - = dst */ 405 cmp r3, r2 /* if (r3 < len) we have an = overlap */ 406 bcc PIC_SYM(_C_LABEL(memcpy), PLT) . . . head/lib/libc/arm/string/memmove.S ( -r288373 ) has: 37 #ifndef _BCOPY 38 /* LINTSTUB: Func: void *memmove(void *, const void *, size_t) = */ 39 ENTRY(memmove) 40 #else 41 /* bcopy =3D memcpy/memmove with arguments reversed. */ 42 /* LINTSTUB: Func: void bcopy(void *, void *, size_t) */ 43 ENTRY(bcopy) 44 /* switch the source and destination registers */ 45 eor r0, r1, r0=20 46 eor r1, r0, r1=20 47 eor r0, r1, r0=20 48 #endif 49 /* Do the buffers overlap? */ 50 cmp r0, r1 51 it eq 52 RETeq /* Bail now if src/dst are the same */ 53 ite cc 54 subcc r3, r0, r1 /* if (dst > src) r3 =3D dst - = src */ 55 subcs r3, r1, r0 /* if (src > dsr) r3 =3D src - = dst */ 56 cmp r3, r2 /* if (r3 < len) we have an = overlap */ 57 bcc PIC_SYM(_C_LABEL(memcpy), PLT) . . . It looks to me like bcopy and memmove call memcpy under some conditions, not the other way around. I did not notice any code in memcpy going back to bcopy (or memmove) in either area. (That might have lead to recursion as things are.) Also netbsd "fixed" the above code for picking when to use memcpy a few years ago (without making the comments accurately track the details as I remember). By my understanding the new netbsd code was the correct variant but others commenting for bugzilla 217065 disagreed. (My comments for 217065 were clearly as I was figuring things out for unfamiliar material. So they are not simple/clean. But I still reach the same conclusions as I eventually did there.) Another issue is if compilers (clang, gcc) are well controlled for code substitutions to preserve supposed FreeBSD rules about where overlaps are well defined. The library code might not be all there is to it as far as behavior goes for compiled C/C++ source code. head/sys/arm64/arm64/ is similar for bcopy/memmove calling memcpy (but head/lib/libc/amd64/string/ is not): head/sys/arm64/arm64/memmove.S ( -r307909 ) has: 87 ENTRY(bcopy) 88 /* Switch the input pointers when called as bcopy */ 89 mov x3, x1 90 mov x1, x0 91 mov x0, x3 92 EENTRY(memmove) 93 sub tmp1, dstin, src 94 cmp count, 96 95 ccmp tmp1, count, 2, hi 96 b.hs memcpy . . . head/lib/libc/amd64/string/bcopy.S has: 44 #ifdef MEMCOPY 45 ENTRY(memcpy) 46 #else 47 #ifdef MEMMOVE 48 ENTRY(memmove) 49 #else 50 ENTRY(bcopy) 51 #endif 52 #endif 53 #if defined(MEMCOPY) || defined(MEMMOVE) 54 movq %rdi,%rax /* return dst */ 55 #else 56 xchgq %rdi,%rsi 57 #endif . . . (the rest being the same for the 3 routines) . . . > mips is backwards for bcopy() and implements it as > memmove(). mips has 2 separate memcpy*.S files, one for plain = arm > and one for xscale. The plain arm one is smaller than memmove.S, > so presumably doesn't support overlapped copies. The xscale one > is much larger, so has space for overlapped copies and many = optimizations > that no longer work. I don't know what it does. The mix of "mips" and "arm"/"xscale" above confused me. Looking around this seems to be referencing head/lib/libc/arm/string/ materials instead of head/lib/libc/mips/string/ or head/sys/mips/mips/ materials. =3D=3D=3D Mark Millard markmi at dsl-only.net