init.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #include <assert.h>
  2. #include <priv-vars.h>
  3. #include <stdlib.h>
  4. #include <syscall.h>
  5. #include <stdio.h>
  6. #include <unistd.h>
  7. #include <list.h>
  8. FILE* stdout;
  9. FILE* stdin;
  10. FILE* stderr;
  11. #define BYTES_PER_MAX_COPY_UNIT (sizeof(uint32_t) / sizeof(uint8_t))
  12. static void* _memset(void* _dst, int c, size_t n)
  13. {
  14. uint8_t* dst = (uint8_t*)_dst;
  15. c &= 0xff;
  16. int cc = (c + (c << 8) + (c << 16) + (c << 24));
  17. for (size_t i = 0; i < n / BYTES_PER_MAX_COPY_UNIT; ++i) {
  18. *(uint32_t*)dst = cc;
  19. dst += BYTES_PER_MAX_COPY_UNIT;
  20. }
  21. for (size_t i = 0; i < (n % BYTES_PER_MAX_COPY_UNIT); ++i) {
  22. *((char*)dst++) = c;
  23. }
  24. return dst;
  25. }
  26. static char* strchr(const char* s, int c)
  27. {
  28. while (*s) {
  29. if (*s == c)
  30. return (char*)s;
  31. ++s;
  32. }
  33. return NULL;
  34. }
  35. list_head* __io_files_location(void)
  36. {
  37. static list_head __io_files;
  38. return &__io_files;
  39. }
  40. size_t* __environ_size_location(void)
  41. {
  42. static size_t __environ_size;
  43. return &__environ_size;
  44. }
  45. void __init_gblibc(int argc, char** argv, char** envp)
  46. {
  47. (void)argc, (void)argv;
  48. // initialize program break position and heap
  49. start_brk = curr_brk = (void*)syscall1(SYS_brk, (uint32_t)NULL);
  50. sbrk(128 * 1024);
  51. struct mem* first = start_brk;
  52. first->sz = 0;
  53. first->flag = 0;
  54. // save environ vector
  55. environ_size = 4;
  56. environ = malloc(environ_size * sizeof(char*));
  57. assert(environ);
  58. while (*envp) {
  59. char* eqp = strchr(*envp, '=');
  60. if (!eqp || eqp == *envp)
  61. goto next;
  62. *eqp = 0;
  63. char* value = eqp + 1;
  64. setenv(*envp, value, 1);
  65. next:;
  66. ++envp;
  67. }
  68. // stdout, stdin, stderr objects
  69. list_node* node = NULL;
  70. // stdout
  71. node = NEWNODE(FILE);
  72. stdout = &NDDATA(*node, FILE);
  73. _memset(stdout, 0x00, sizeof(FILE));
  74. stdout->fd = STDOUT_FILENO;
  75. stdout->flags = FILE_WRITE;
  76. stdout->wbuf = malloc(BUFSIZ);
  77. stdout->wbsz = BUFSIZ;
  78. NDINSERT(&iofiles, node);
  79. // stdin
  80. node = NEWNODE(FILE);
  81. stdin = &NDDATA(*node, FILE);
  82. _memset(stdin, 0x00, sizeof(FILE));
  83. stdin->fd = STDIN_FILENO;
  84. stdin->flags = FILE_READ;
  85. stdin->rbuf = malloc(BUFSIZ);
  86. stdin->rbsz = BUFSIZ;
  87. NDINSERT(&iofiles, node);
  88. // stderr
  89. node = NEWNODE(FILE);
  90. stderr = &NDDATA(*node, FILE);
  91. _memset(stderr, 0x00, sizeof(FILE));
  92. stderr->fd = STDERR_FILENO;
  93. stderr->flags = FILE_WRITE;
  94. NDINSERT(&iofiles, node);
  95. }