string.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /*
  2. * This provides an optimized implementation of memcpy, and a simplified
  3. * implementation of memset and memmove. These are used here because the
  4. * standard kernel runtime versions are not yet available and we don't
  5. * trust the gcc built-in implementations as they may do unexpected things
  6. * (e.g. FPU ops) in the minimal decompression stub execution environment.
  7. */
  8. #include "error.h"
  9. #include "../string.c"
  10. #ifdef CONFIG_X86_32
  11. static void *__memcpy(void *dest, const void *src, size_t n)
  12. {
  13. int d0, d1, d2;
  14. asm volatile(
  15. "rep ; movsl\n\t"
  16. "movl %4,%%ecx\n\t"
  17. "rep ; movsb\n\t"
  18. : "=&c" (d0), "=&D" (d1), "=&S" (d2)
  19. : "0" (n >> 2), "g" (n & 3), "1" (dest), "2" (src)
  20. : "memory");
  21. return dest;
  22. }
  23. #else
  24. static void *__memcpy(void *dest, const void *src, size_t n)
  25. {
  26. long d0, d1, d2;
  27. asm volatile(
  28. "rep ; movsq\n\t"
  29. "movq %4,%%rcx\n\t"
  30. "rep ; movsb\n\t"
  31. : "=&c" (d0), "=&D" (d1), "=&S" (d2)
  32. : "0" (n >> 3), "g" (n & 7), "1" (dest), "2" (src)
  33. : "memory");
  34. return dest;
  35. }
  36. #endif
  37. void *memset(void *s, int c, size_t n)
  38. {
  39. int i;
  40. char *ss = s;
  41. for (i = 0; i < n; i++)
  42. ss[i] = c;
  43. return s;
  44. }
  45. void *memmove(void *dest, const void *src, size_t n)
  46. {
  47. unsigned char *d = dest;
  48. const unsigned char *s = src;
  49. if (d <= s || d - s >= n)
  50. return __memcpy(dest, src, n);
  51. while (n-- > 0)
  52. d[n] = s[n];
  53. return dest;
  54. }
  55. /* Detect and warn about potential overlaps, but handle them with memmove. */
  56. void *memcpy(void *dest, const void *src, size_t n)
  57. {
  58. if (dest > src && dest - src < n) {
  59. warn("Avoiding potentially unsafe overlapping memcpy()!");
  60. return memmove(dest, src, n);
  61. }
  62. return __memcpy(dest, src, n);
  63. }