StdLib.cpp 4.8 KB

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