StdLib.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #include <AK/Assertions.h>
  2. #include <AK/Types.h>
  3. #include <Kernel/Heap/kmalloc.h>
  4. extern "C" {
  5. void* memcpy(void* dest_ptr, const void* src_ptr, size_t n)
  6. {
  7. size_t dest = (size_t)dest_ptr;
  8. size_t src = (size_t)src_ptr;
  9. // FIXME: Support starting at an unaligned address.
  10. if (!(dest & 0x3) && !(src & 0x3) && n >= 12) {
  11. size_t size_ts = n / sizeof(size_t);
  12. asm volatile(
  13. "rep movsl\n"
  14. : "=S"(src), "=D"(dest)
  15. : "S"(src), "D"(dest), "c"(size_ts)
  16. : "memory");
  17. n -= size_ts * sizeof(size_t);
  18. if (n == 0)
  19. return dest_ptr;
  20. }
  21. asm volatile(
  22. "rep movsb\n" ::"S"(src), "D"(dest), "c"(n)
  23. : "memory");
  24. return dest_ptr;
  25. }
  26. void* memmove(void* dest, const void* src, size_t n)
  27. {
  28. if (dest < src)
  29. return memcpy(dest, src, n);
  30. u8* pd = (u8*)dest;
  31. const u8* ps = (const u8*)src;
  32. for (pd += n, ps += n; n--;)
  33. *--pd = *--ps;
  34. return dest;
  35. }
  36. char* strcpy(char* dest, const char* src)
  37. {
  38. auto* dest_ptr = dest;
  39. auto* src_ptr = src;
  40. while ((*dest_ptr++ = *src_ptr++) != '\0')
  41. ;
  42. return dest;
  43. }
  44. char* strncpy(char* dest, const char* src, size_t n)
  45. {
  46. size_t i;
  47. for (i = 0; i < n && src[i] != '\0'; ++i)
  48. dest[i] = src[i];
  49. for (; i < n; ++i)
  50. dest[i] = '\0';
  51. return dest;
  52. }
  53. void* memset(void* dest_ptr, int c, size_t n)
  54. {
  55. size_t dest = (size_t)dest_ptr;
  56. // FIXME: Support starting at an unaligned address.
  57. if (!(dest & 0x3) && n >= 12) {
  58. size_t size_ts = n / sizeof(size_t);
  59. size_t expanded_c = (u8)c;
  60. expanded_c |= expanded_c << 8;
  61. expanded_c |= expanded_c << 16;
  62. asm volatile(
  63. "rep stosl\n"
  64. : "=D"(dest)
  65. : "D"(dest), "c"(size_ts), "a"(expanded_c)
  66. : "memory");
  67. n -= size_ts * sizeof(size_t);
  68. if (n == 0)
  69. return dest_ptr;
  70. }
  71. asm volatile(
  72. "rep stosb\n"
  73. : "=D"(dest), "=c"(n)
  74. : "0"(dest), "1"(n), "a"(c)
  75. : "memory");
  76. return dest_ptr;
  77. }
  78. char* strrchr(const char* str, int ch)
  79. {
  80. char* last = nullptr;
  81. char c;
  82. for (; (c = *str); ++str) {
  83. if (c == ch)
  84. last = const_cast<char*>(str);
  85. }
  86. return last;
  87. }
  88. size_t strlen(const char* str)
  89. {
  90. size_t len = 0;
  91. while (*(str++))
  92. ++len;
  93. return len;
  94. }
  95. size_t strnlen(const char* str, size_t maxlen)
  96. {
  97. size_t len = 0;
  98. for (; len < maxlen && *str; str++)
  99. len++;
  100. return len;
  101. }
  102. int strcmp(const char* s1, const char* s2)
  103. {
  104. for (; *s1 == *s2; ++s1, ++s2) {
  105. if (*s1 == 0)
  106. return 0;
  107. }
  108. return *(const u8*)s1 < *(const u8*)s2 ? -1 : 1;
  109. }
  110. char* strdup(const char* str)
  111. {
  112. size_t len = strlen(str);
  113. char* new_str = (char*)kmalloc(len + 1);
  114. strcpy(new_str, str);
  115. return new_str;
  116. }
  117. int memcmp(const void* v1, const void* v2, size_t n)
  118. {
  119. auto* s1 = (const u8*)v1;
  120. auto* s2 = (const u8*)v2;
  121. while (n-- > 0) {
  122. if (*s1++ != *s2++)
  123. return s1[-1] < s2[-1] ? -1 : 1;
  124. }
  125. return 0;
  126. }
  127. int strncmp(const char* s1, const char* s2, size_t n)
  128. {
  129. if (!n)
  130. return 0;
  131. do {
  132. if (*s1 != *s2++)
  133. return *(const unsigned char*)s1 - *(const unsigned char*)--s2;
  134. if (*s1++ == 0)
  135. break;
  136. } while (--n);
  137. return 0;
  138. }
  139. char* strstr(const char* haystack, const char* needle)
  140. {
  141. char nch;
  142. char hch;
  143. if ((nch = *needle++) != 0) {
  144. size_t len = strlen(needle);
  145. do {
  146. do {
  147. if ((hch = *haystack++) == 0)
  148. return nullptr;
  149. } while (hch != nch);
  150. } while (strncmp(haystack, needle, len) != 0);
  151. --haystack;
  152. }
  153. return const_cast<char*>(haystack);
  154. }
  155. [[noreturn]] void __cxa_pure_virtual()
  156. {
  157. ASSERT_NOT_REACHED();
  158. }
  159. void* realloc(void* p, size_t s)
  160. {
  161. return krealloc(p, s);
  162. }
  163. void free(void* p)
  164. {
  165. return kfree(p);
  166. }
  167. }