32 lines
927 B
C
32 lines
927 B
C
|
/*
|
||
|
* Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved.
|
||
|
*
|
||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||
|
*/
|
||
|
|
||
|
#include <string.h>
|
||
|
|
||
|
void *memmove(void *dst, const void *src, size_t 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;
|
||
|
}
|