summaryrefslogtreecommitdiff
path: root/sys/lib/libkern/arch
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2013-06-15 18:51:45 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2013-06-15 18:51:45 +0000
commitcbe7b45c963ee195eff9fa9b3130be9aafc54d9a (patch)
tree033fb292ae4051050fd85ad0b63b2db8b3891f61 /sys/lib/libkern/arch
parent61e3acb3cc42e6ec3e34d4d55cc01c7f2648ad72 (diff)
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