memmove.c 927 B

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