Fix memmove and memcpy

memmove needs to allow for overlapping memory regions and, together
with memcpy, should return the input destination pointer, not the
address after the end of the copied data.

fixes ARM-software/tf-issues#18

Signed-off-by: Jon Medhurst <tixy@linaro.org>
This commit is contained in:
Jon Medhurst 2014-01-15 18:22:34 +00:00 committed by Dan Handley
parent 36eaaf3769
commit c3810c83aa
1 changed files with 26 additions and 8 deletions

View File

@ -63,29 +63,47 @@ int memcmp(const void *s1, const void *s2, size_t len)
return 0;
}
/*
* Move @len bytes from @src to @dst
* Copy @len bytes from @src to @dst
*/
void *memmove(void *dst, const void *src, size_t len)
void *memcpy(void *dst, const void *src, size_t len)
{
const char *s = src;
char *d = dst;
while (len--)
*d++ = *s++;
return d;
return dst;
}
/*
* Copy @len bytes from @src to @dst
* Move @len bytes from @src to @dst
*/
void *memcpy(void *dst, const void *src, size_t len)
void *memmove(void *dst, const void *src, size_t len)
{
return memmove(dst, src, len);
/*
* The following test makes use of unsigned arithmetic overflow to
* more efficiently test the condition !(src <= dst && dst < str+len).
* It also avoids the situation where the more explicit test would give
* incorrect results were the calculation str+len to overflow (though
* that issue is probably moot as such usage is probably undefined
* behaviour and a bug anyway.
*/
if ((size_t)dst - (size_t)src >= len) {
/* destination not in source data, so can safely use memcpy */
return memcpy(dst, src, len);
} else {
/* copy backwards... */
const char *end = dst;
const char *s = (const char *)src + len;
char *d = (char *)dst + len;
while (d != end)
*--d = *--s;
}
return dst;
}
/*
* Scan @len bytes of @src for value @c
*/