summaryrefslogtreecommitdiffstats
path: root/sys/lib/libkern/arch
diff options
context:
space:
mode:
authormiod <miod@openbsd.org>2013-06-15 18:51:44 +0000
committermiod <miod@openbsd.org>2013-06-15 18:51:44 +0000
commitcda765abcdd837f8d89352d7d29ad5881ca71284 (patch)
treed7135599700df27c30cdb0a7cdbb8ff5d33084e6 /sys/lib/libkern/arch
parentDon't return garbage in memcpy() but the original destination pointer. (diff)
downloadwireguard-openbsd-cda765abcdd837f8d89352d7d29ad5881ca71284.tar.xz
wireguard-openbsd-cda765abcdd837f8d89352d7d29ad5881ca71284.zip
Correctly handle a length of zero in memcpy().
Return the original destination pointer in memcpy() and memmove().
Diffstat (limited to 'sys/lib/libkern/arch')
-rw-r--r--sys/lib/libkern/arch/alpha/memmove.S21
1 files changed, 14 insertions, 7 deletions
diff --git a/sys/lib/libkern/arch/alpha/memmove.S b/sys/lib/libkern/arch/alpha/memmove.S
index 2a994c8ab1a..63ff77ca272 100644
--- a/sys/lib/libkern/arch/alpha/memmove.S
+++ b/sys/lib/libkern/arch/alpha/memmove.S
@@ -31,20 +31,27 @@
* Copy a bytes within the kernel's address space. The bcopy and memmove
* variants handle overlapping regions, the memcpy variant does not.
*
- * void memcpy(char *to, char *from, size_t len);
- * void memmove(char *to, char *from, size_t len);
- * void bcopy(char *from, char *to, size_t len);
+ * void* memcpy(void *to, void *from, size_t len);
+ * void* memmove(void *to, void *from, size_t len);
+ * void bcopy(void *from, void *to, size_t len);
*/
LEAF(memcpy,3)
- cmoveq zero,a0,t5
+ /* Swap arguments, also saving the original `from' in v0 */
+ cmoveq zero,a0,v0
cmoveq zero,a1,a0
- cmoveq zero,t5,a1
+ cmoveq zero,v0,a1
+
+ /* Check for zero length */
+ beq a2,bcopy_done
+
br bcopy_forward
XLEAF(memmove,3)
- cmoveq zero,a0,t5
+ /* Swap arguments, also saving the original `from' in v0 */
+ cmoveq zero,a0,v0
cmoveq zero,a1,a0
- cmoveq zero,t5,a1
+ cmoveq zero,v0,a1
+
XLEAF(bcopy,3)
/* Check for zero length */
beq a2,bcopy_done