1*4661abc7SAntonio Nino Diaz /* 2*4661abc7SAntonio Nino Diaz * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. 3*4661abc7SAntonio Nino Diaz * 4*4661abc7SAntonio Nino Diaz * SPDX-License-Identifier: BSD-3-Clause 5*4661abc7SAntonio Nino Diaz */ 6*4661abc7SAntonio Nino Diaz 7*4661abc7SAntonio Nino Diaz #include <string.h> 8*4661abc7SAntonio Nino Diaz 9*4661abc7SAntonio Nino Diaz void *memmove(void *dst, const void *src, size_t len) 10*4661abc7SAntonio Nino Diaz { 11*4661abc7SAntonio Nino Diaz /* 12*4661abc7SAntonio Nino Diaz * The following test makes use of unsigned arithmetic overflow to 13*4661abc7SAntonio Nino Diaz * more efficiently test the condition !(src <= dst && dst < str+len). 14*4661abc7SAntonio Nino Diaz * It also avoids the situation where the more explicit test would give 15*4661abc7SAntonio Nino Diaz * incorrect results were the calculation str+len to overflow (though 16*4661abc7SAntonio Nino Diaz * that issue is probably moot as such usage is probably undefined 17*4661abc7SAntonio Nino Diaz * behaviour and a bug anyway. 18*4661abc7SAntonio Nino Diaz */ 19*4661abc7SAntonio Nino Diaz if ((size_t)dst - (size_t)src >= len) { 20*4661abc7SAntonio Nino Diaz /* destination not in source data, so can safely use memcpy */ 21*4661abc7SAntonio Nino Diaz return memcpy(dst, src, len); 22*4661abc7SAntonio Nino Diaz } else { 23*4661abc7SAntonio Nino Diaz /* copy backwards... */ 24*4661abc7SAntonio Nino Diaz const char *end = dst; 25*4661abc7SAntonio Nino Diaz const char *s = (const char *)src + len; 26*4661abc7SAntonio Nino Diaz char *d = (char *)dst + len; 27*4661abc7SAntonio Nino Diaz while (d != end) 28*4661abc7SAntonio Nino Diaz *--d = *--s; 29*4661abc7SAntonio Nino Diaz } 30*4661abc7SAntonio Nino Diaz return dst; 31*4661abc7SAntonio Nino Diaz } 32