#ifdef HAVE_CONFIG_H #include #endif #include /* * Copy n bytes from src to dst. The regions may overlap, so the copy * direction is chosen by the relative positions: forward when dst starts * at or before src, or at or after the end of src; backward when dst * starts inside src. Word-at-a-time in both directions, with byte heads * and tails; word loads and stores go through __builtin_memcpy. */ void * memmove(void *dst, const void *src, size_t n) // NOLINT(bugprone-easily-swappable-parameters) { const unsigned long word = sizeof(unsigned long); unsigned char *d = dst; const unsigned char *s = src; if (d <= s || d >= s + n) { /* Forward copy. */ for (; (unsigned long)d % word != 0 && n != 0; n--) { *d++ = *s++; } while (n >= word) { unsigned long w; __builtin_memcpy(&w, s, sizeof w); // NOLINT(clang-analyzer-security.insecureAPI.*) __builtin_memcpy(d, &w, sizeof w); // NOLINT(clang-analyzer-security.insecureAPI.*) d += word; s += word; n -= word; } while (n != 0) { *d++ = *s++; n--; } } else { /* Backward copy, starting from the last byte. */ d += n; s += n; for (; (unsigned long)d % word != 0 && n != 0; n--) { *--d = *--s; } while (n >= word) { unsigned long w; d -= word; s -= word; __builtin_memcpy(&w, s, sizeof w); // NOLINT(clang-analyzer-security.insecureAPI.*) __builtin_memcpy(d, &w, sizeof w); // NOLINT(clang-analyzer-security.insecureAPI.*) n -= word; } while (n != 0) { *--d = *--s; n--; } } return dst; }