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