stdlib.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #include <stdlib.h>
  2. #include <sys/mman.h>
  3. #include <stdio.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6. #include <alloca.h>
  7. #include <assert.h>
  8. #include <Kernel/Syscall.h>
  9. #include <AK/Assertions.h>
  10. extern "C" {
  11. // FIXME: This is a temporary malloc() implementation. It never frees anything,
  12. // and you can't allocate more than 128 kB total.
  13. static const size_t mallocBudget = 131072;
  14. static byte* nextptr = nullptr;
  15. static byte* endptr = nullptr;
  16. void __malloc_init()
  17. {
  18. nextptr = (byte*)mmap(nullptr, mallocBudget, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
  19. endptr = nextptr + mallocBudget;
  20. int rc = set_mmap_name(nextptr, mallocBudget, "malloc");
  21. if (rc < 0)
  22. perror("set_mmap_name failed");
  23. }
  24. void* malloc(size_t size)
  25. {
  26. if ((nextptr + size) > endptr) {
  27. fprintf(stderr, "Unable to serve malloc() request with size %u\n", size);
  28. volatile char* crashme = (char*)0xc007d00d;
  29. *crashme = 0;
  30. }
  31. byte* ret = nextptr;
  32. nextptr += size;
  33. nextptr += 16;
  34. nextptr = (byte*)((dword)nextptr & 0xfffffff0);
  35. return ret;
  36. }
  37. void free(void* ptr)
  38. {
  39. if (!ptr)
  40. return;
  41. #if 0
  42. munmap(ptr, 4096);
  43. #endif
  44. }
  45. void* calloc(size_t nmemb, size_t)
  46. {
  47. (void) nmemb;
  48. ASSERT_NOT_REACHED();
  49. return nullptr;
  50. }
  51. void* realloc(void *ptr, size_t size)
  52. {
  53. // FIXME: This is broken as shit.
  54. auto* new_ptr = malloc(size);
  55. memcpy(new_ptr, ptr, size);
  56. return new_ptr;
  57. }
  58. void exit(int status)
  59. {
  60. Syscall::invoke(Syscall::SC_exit, (dword)status);
  61. for (;;);
  62. }
  63. void abort()
  64. {
  65. // FIXME: Implement proper abort().
  66. exit(253);
  67. }
  68. char* getenv(const char* name)
  69. {
  70. for (size_t i = 0; environ[i]; ++i) {
  71. const char* decl = environ[i];
  72. char* eq = strchr(decl, '=');
  73. if (!eq)
  74. continue;
  75. size_t varLength = eq - decl;
  76. char* var = (char*)alloca(varLength + 1);
  77. memcpy(var, decl, varLength);
  78. var[varLength] = '\0';
  79. if (!strcmp(var, name)) {
  80. char* value = eq + 1;
  81. return value;
  82. }
  83. }
  84. return nullptr;
  85. }
  86. int atoi(const char* str)
  87. {
  88. size_t len = strlen(str);
  89. int value = 0;
  90. bool isNegative = false;
  91. for (size_t i = 0; i < len; ++i) {
  92. if (i == 0 && str[0] == '-') {
  93. isNegative = true;
  94. continue;
  95. }
  96. if (str[i] < '0' || str[i] > '9')
  97. return value;
  98. value = value * 10;
  99. value += str[i] - '0';
  100. }
  101. return isNegative ? -value : value;
  102. }
  103. long atol(const char* str)
  104. {
  105. static_assert(sizeof(int) == sizeof(long));
  106. return atoi(str);
  107. }
  108. void __qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *))
  109. {
  110. (void) base;
  111. (void) nmemb;
  112. (void) size;
  113. (void) compar;
  114. assert(false);
  115. }
  116. }