blob: b8acb6579a72e3081880b10a011a9cfac366d21c [file] [log] [blame]
/*
* SPDX-License-Identifier: BSD-3-Clause
* SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
* SPDX-FileCopyrightText: Copyright Jon Medhurst <tixy@linaro.org>
*/
#include <stddef.h>
#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);
}
/* 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;
}