Advertisement
Guest User

Untitled

a guest
Apr 19th, 2019
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.32 KB | None | 0 0
  1. /*
  2. * Loader Implementation
  3. *
  4. * 2018, Operating Systems
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include <signal.h>
  11. #include <fcntl.h>
  12. #include <sys/mman.h>
  13. #include <unistd.h>
  14.  
  15.  
  16. #include "exec_parser.h"
  17.  
  18. int fd;
  19. static so_exec_t *exec;
  20. struct sigaction signals;
  21. static struct sigaction old_action;
  22.  
  23. static void segv_handler(int signum, siginfo_t *info, void *context) {
  24. so_seg_t *seg;
  25. so_seg_t *segment;
  26. uintptr_t addr;
  27. if (info->si_code == SEGV_ACCERR) {
  28. old_action.sa_sigaction(signum, info, context);
  29. return;
  30. }
  31. switch (signum) {
  32. case SIGSEGV:
  33. addr = (uintptr_t)info->si_addr;
  34. int found = 0;
  35. for(int i = 0; i < exec->segments_no; i++) {
  36. seg = exec->segments + i;
  37. if(seg->vaddr <= addr && addr <= (seg->vaddr + seg->mem_size)) {
  38. segment = seg;
  39. found = 1;
  40. }
  41. }
  42. if(found == 0) {
  43. goto default_h;
  44. }
  45. uintptr_t page = ALIGN_DOWN((uintptr_t)info->si_addr, getpagesize());
  46. uintptr_t offset_p = page - ALIGN_DOWN(segment->vaddr, getpagesize());
  47. if(page + getpagesize() <= (segment->vaddr + segment->file_size) || segment->file_size == segment->mem_size) {
  48. void* rc = mmap((void *)page, getpagesize(), segment->perm,
  49. MAP_PRIVATE | MAP_FIXED, fd, segment->offset + offset_p);
  50.  
  51. } else if(page <= (segment->vaddr + segment->file_size)) {
  52. void* rc = mmap((void *)page, getpagesize(), segment->perm,
  53. MAP_PRIVATE | MAP_ANONYMOUS, -1, segment->offset + offset_p);
  54. if(rc == MAP_FAILED) {
  55. goto default_h;
  56. }
  57. lseek(fd, segment->offset + offset_p, SEEK_SET);
  58. read(fd, rc, segment->vaddr + segment->file_size - page);
  59. } else if(page >= (segment->vaddr + segment->file_size)) {
  60. mmap((void *)page, getpagesize(), segment->perm,
  61. MAP_PRIVATE | MAP_ANONYMOUS, -1, segment->offset + offset_p);
  62. }
  63. break;
  64. default:
  65. default_h:
  66. old_action.sa_sigaction(signum, info, context);
  67. }
  68. }
  69.  
  70. int so_init_loader(void)
  71. {
  72. /* TODO: initialize on-demand loader */
  73. struct sigaction action;
  74. int rc;
  75.  
  76. action.sa_flags = SA_SIGINFO;
  77. action.sa_sigaction = segv_handler;
  78.  
  79. rc = sigaction(SIGSEGV, &action, &old_action);
  80.  
  81. return rc;
  82. }
  83.  
  84. int so_execute(char *path, char *argv[])
  85. {
  86. exec = so_parse_exec(path);
  87. if (!exec)
  88. return -1;
  89.  
  90. fd = open(path, O_RDONLY);
  91.  
  92. so_start_exec(exec, argv);
  93.  
  94. return -1;
  95. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement