Advertisement
Guest User

Untitled

a guest
Apr 24th, 2019
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.68 KB | None | 0 0
  1. /*
  2. * Loader Implementation
  3. *
  4. * 2018, Operating Systems
  5. */
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include <signal.h>
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include <unistd.h>
  13. #include <fcntl.h>
  14. #include <sys/mman.h>
  15. #include "exec_parser.h"
  16. #define page_size sysconf(_SC_PAGE_SIZE)
  17.  
  18. static so_exec_t *exec;
  19. static int fd;
  20.  
  21. static void* sigsegv_handler(int signum, siginfo_t *info, void *ucontext)
  22. {
  23. int i;
  24.  
  25. for (i = 0; i < exec->segments_no; ++i) {
  26.  
  27. int addr_to_map = (int)info->si_addr;
  28.  
  29. if (addr_to_map < exec->segments[i].vaddr +
  30. exec->segments[i].mem_size
  31. && addr_to_map >= exec->segments[i].vaddr) {
  32.  
  33. if (exec->segments[i].data == NULL) {
  34. int nr = exec->segments[i].mem_size / page_size;
  35.  
  36. exec->segments[i].data =
  37. (int *)calloc(nr + 1, sizeof(int));
  38. }
  39.  
  40. int addr = exec->segments[i].vaddr;
  41. int page_count = 0;
  42.  
  43. while (addr + page_size <= addr_to_map) {
  44. addr += page_size;
  45. page_count++;
  46. }
  47.  
  48. int *p = exec->segments[i].data;
  49.  
  50. if (p[page_count] != 0) {
  51. signal(SIGSEGV, SIG_DFL);
  52. raise(SIGSEGV);
  53. signal(SIGSEGV, (void *)(int)sigsegv_handler);
  54. }
  55. p[page_count] = 1;
  56.  
  57. void *x = mmap((void *)addr, page_size,
  58. PROT_WRITE,
  59. MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
  60. if (x < 0)
  61. return (void *)-1;
  62.  
  63. void *read_buf = malloc(page_size);
  64.  
  65. lseek(fd, exec->segments[i].offset +
  66. page_count * page_size, SEEK_SET);
  67.  
  68. int to_read = page_size;
  69.  
  70. if (addr + page_size >
  71. exec->segments[i].vaddr +
  72. exec->segments[i].file_size)
  73. to_read = exec->segments[i].file_size %
  74. page_size;
  75.  
  76.  
  77. if (addr > exec->segments[i].vaddr +
  78. exec->segments[i].file_size)
  79. to_read = 0;
  80.  
  81.  
  82. int rc = read(fd, read_buf, to_read);
  83.  
  84. if (rc < 0)
  85. return (void *)-1;
  86.  
  87.  
  88. if (rc < page_size)
  89. memset(read_buf + rc, 0, page_size - rc);
  90.  
  91. memcpy((void *)addr, read_buf, page_size);
  92.  
  93. rc = mprotect((void *)addr, page_size,
  94. exec->segments[i].perm);
  95. free(read_buf);
  96. return 0;
  97. }
  98. }
  99. signal(SIGSEGV, SIG_DFL);
  100. raise(SIGSEGV);
  101. signal(SIGSEGV, (void *)(int)sigsegv_handler);
  102.  
  103. return (void *)-1;
  104. }
  105.  
  106. int so_init_loader(void)
  107. {
  108. /* TODO: initialize on-demand loader */
  109. struct sigaction sa;
  110.  
  111. memset(&sa, 0, sizeof(sa));
  112. sa.sa_sigaction = (void *)&sigsegv_handler;
  113. sa.sa_flags = SA_SIGINFO | SA_NODEFER;
  114.  
  115. sigaction(SIGSEGV, &sa, NULL);
  116.  
  117.  
  118. return -1;
  119. }
  120.  
  121. int so_execute(char *path, char *argv[])
  122. {
  123.  
  124. exec = so_parse_exec(path);
  125. if (!exec)
  126. return -1;
  127.  
  128. fd = open(path, O_RDONLY);
  129. if (fd < 0)
  130. exit(-1);
  131.  
  132.  
  133. so_start_exec(exec, argv);
  134.  
  135. close(fd);
  136.  
  137. return -1;
  138. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement