Advertisement
Guest User

Untitled

a guest
Apr 19th, 2019
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.45 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. switch (signum) {
  28. case SIGSEGV:
  29. addr = (uintptr_t)info->si_addr;
  30. int found = 0;
  31. for(int i = 0; i < exec->segments_no; i++) {
  32. seg = exec->segments + i;
  33. if(seg->vaddr <= addr && addr <= (seg->vaddr + seg->mem_size)) {
  34. segment = seg;
  35. found = 1;
  36. }
  37. }
  38. if(found == 0) {
  39. goto default_h;
  40. }
  41. /*int index = (addr - segment->vaddr) / getpagesize();
  42. uintptr_t page = segment->vaddr + index * getpagesize();*/
  43. uintptr_t page = ALIGN_DOWN((uintptr_t)info->si_addr, getpagesize());
  44. uintptr_t offset_p = ALIGN_DOWN((uintptr_t)info->si_addr - segment->vaddr, getpagesize());
  45. if(page + getpagesize() <= (segment->vaddr + segment->file_size)) {
  46. void* rc = mmap((void *)page, getpagesize(), segment->perm,
  47. MAP_PRIVATE | MAP_FIXED, fd, segment->offset + offset_p);
  48. if(rc == MAP_FAILED) {
  49. goto default_h;
  50. }
  51. } else if(page <= (segment->vaddr + segment->file_size)) {
  52. void* rc = mmap((void *)page, getpagesize(), PROT_WRITE | PROT_READ,
  53. MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -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. mprotect((void *)page, getpagesize(), segment->perm);
  60. } else if(page >= (segment->vaddr + segment->file_size)) {
  61. mmap((void *)page, getpagesize(), segment->perm,
  62. MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, segment->offset + offset_p);
  63. }
  64.  
  65. default:
  66. default_h:
  67. old_action.sa_sigaction(signum, info, context);
  68. }
  69. }
  70.  
  71. int so_init_loader(void)
  72. {
  73. /* TODO: initialize on-demand loader */
  74. struct sigaction action;
  75. int rc;
  76.  
  77. action.sa_flags = SA_SIGINFO;
  78. action.sa_sigaction = segv_handler;
  79.  
  80. rc = sigaction(SIGSEGV, &action, &old_action);
  81.  
  82. return rc;
  83. }
  84.  
  85. int so_execute(char *path, char *argv[])
  86. {
  87. exec = so_parse_exec(path);
  88. if (!exec)
  89. return -1;
  90.  
  91. fd = open(path, O_RDONLY);
  92.  
  93. so_start_exec(exec, argv);
  94.  
  95. return -1;
  96. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement