blob: b8acb6579a72e3081880b10a011a9cfac366d21c [file] [log] [blame]
Soby Mathewb4c6df42022-11-09 11:13:29 +00001/*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4 * SPDX-FileCopyrightText: Copyright Jon Medhurst <tixy@linaro.org>
5 */
6
7#include <stddef.h>
8#include <string.h>
9
10void *memmove(void *dst, const void *src, size_t len)
11{
12 /*
13 * The following test makes use of unsigned arithmetic overflow to
14 * more efficiently test the condition !(src <= dst && dst < str+len).
15 * It also avoids the situation where the more explicit test would give
16 * incorrect results were the calculation str+len to overflow (though
17 * that issue is probably moot as such usage is probably undefined
18 * behaviour and a bug anyway.
19 */
20 if ((size_t)dst - (size_t)src >= len) {
21 /* destination not in source data, so can safely use memcpy */
22 return memcpy(dst, src, len);
23 }
24
25 /* copy backwards... */
26 const char *end = dst;
27 const char *s = (const char *)src + len;
28 char *d = (char *)dst + len;
29
30 while (d != end) {
31 *--d = *--s;
32 }
33 return dst;
34}