14661abc7SAntonio Nino Diaz /* 24c700c15SGovindraj Raja * Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved. 34661abc7SAntonio Nino Diaz * 44661abc7SAntonio Nino Diaz * SPDX-License-Identifier: BSD-3-Clause 54661abc7SAntonio Nino Diaz */ 64661abc7SAntonio Nino Diaz 74661abc7SAntonio Nino Diaz #include <string.h> 84661abc7SAntonio Nino Diaz 94661abc7SAntonio Nino Diaz void *memmove(void *dst, const void *src, size_t len) 104661abc7SAntonio Nino Diaz { 114661abc7SAntonio Nino Diaz /* 124661abc7SAntonio Nino Diaz * The following test makes use of unsigned arithmetic overflow to 134661abc7SAntonio Nino Diaz * more efficiently test the condition !(src <= dst && dst < str+len). 144661abc7SAntonio Nino Diaz * It also avoids the situation where the more explicit test would give 154661abc7SAntonio Nino Diaz * incorrect results were the calculation str+len to overflow (though 164661abc7SAntonio Nino Diaz * that issue is probably moot as such usage is probably undefined 174661abc7SAntonio Nino Diaz * behaviour and a bug anyway. 184661abc7SAntonio Nino Diaz */ 19*277d7dd6SMaheedhar Bollapalli if (((size_t)dst - (size_t)src) >= len) { 204661abc7SAntonio Nino Diaz /* destination not in source data, so can safely use memcpy */ 214661abc7SAntonio Nino Diaz return memcpy(dst, src, len); 224661abc7SAntonio Nino Diaz } else { 234661abc7SAntonio Nino Diaz /* copy backwards... */ 244661abc7SAntonio Nino Diaz const char *end = dst; 254661abc7SAntonio Nino Diaz const char *s = (const char *)src + len; 264661abc7SAntonio Nino Diaz char *d = (char *)dst + len; 274661abc7SAntonio Nino Diaz while (d != end) 284661abc7SAntonio Nino Diaz *--d = *--s; 294661abc7SAntonio Nino Diaz } 304661abc7SAntonio Nino Diaz return dst; 314661abc7SAntonio Nino Diaz } 32