blob: 023420d3dac1e9cff52b7aaa8c20e4640a98f86f [file] [log] [blame]
Antonio Nino Diaz9eddb1e2018-08-16 14:53:05 +01001/*
Govindraj Rajaeee28e72023-08-01 15:52:40 -05002 * Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.
Antonio Nino Diaz9eddb1e2018-08-16 14:53:05 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <string.h>
8
9void *memmove(void *dst, const void *src, size_t len)
10{
11 /*
12 * The following test makes use of unsigned arithmetic overflow to
13 * more efficiently test the condition !(src <= dst && dst < str+len).
14 * It also avoids the situation where the more explicit test would give
15 * incorrect results were the calculation str+len to overflow (though
16 * that issue is probably moot as such usage is probably undefined
17 * behaviour and a bug anyway.
18 */
19 if ((size_t)dst - (size_t)src >= len) {
20 /* destination not in source data, so can safely use memcpy */
21 return memcpy(dst, src, len);
22 } else {
23 /* copy backwards... */
24 const char *end = dst;
25 const char *s = (const char *)src + len;
26 char *d = (char *)dst + len;
Maheedhar Bollapalli2f6ce732024-04-25 12:17:01 +053027 while (d != end) {
Antonio Nino Diaz9eddb1e2018-08-16 14:53:05 +010028 *--d = *--s;
Maheedhar Bollapalli2f6ce732024-04-25 12:17:01 +053029 }
Antonio Nino Diaz9eddb1e2018-08-16 14:53:05 +010030 }
31 return dst;
32}