map.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /*
  2. * file map routines
  3. */
  4. #include <u.h>
  5. #include <libc.h>
  6. #include <bio.h>
  7. #include <mach.h>
  8. Map *
  9. newmap(Map *map, int n)
  10. {
  11. int size;
  12. size = sizeof(Map)+(n-1)*sizeof(struct segment);
  13. if (map == 0)
  14. map = malloc(size);
  15. else
  16. map = realloc(map, size);
  17. if (map == 0) {
  18. werrstr("out of memory: %r");
  19. return 0;
  20. }
  21. memset(map, 0, size);
  22. map->nsegs = n;
  23. return map;
  24. }
  25. int
  26. setmap(Map *map, int fd, uvlong b, uvlong e, vlong f, char *name)
  27. {
  28. int i;
  29. if (map == 0)
  30. return 0;
  31. for (i = 0; i < map->nsegs; i++)
  32. if (!map->seg[i].inuse)
  33. break;
  34. if (i >= map->nsegs)
  35. return 0;
  36. map->seg[i].b = b;
  37. map->seg[i].e = e;
  38. map->seg[i].f = f;
  39. map->seg[i].inuse = 1;
  40. map->seg[i].name = name;
  41. map->seg[i].fd = fd;
  42. return 1;
  43. }
  44. static uvlong
  45. stacktop(int pid)
  46. {
  47. char buf[64];
  48. int fd;
  49. int n;
  50. char *cp;
  51. snprint(buf, sizeof(buf), "/proc/%d/segment", pid);
  52. fd = open(buf, 0);
  53. if (fd < 0)
  54. return 0;
  55. n = read(fd, buf, sizeof(buf)-1);
  56. close(fd);
  57. buf[n] = 0;
  58. if (strncmp(buf, "Stack", 5))
  59. return 0;
  60. for (cp = buf+5; *cp && *cp == ' '; cp++)
  61. ;
  62. if (!*cp)
  63. return 0;
  64. cp = strchr(cp, ' ');
  65. if (!cp)
  66. return 0;
  67. while (*cp && *cp == ' ')
  68. cp++;
  69. if (!*cp)
  70. return 0;
  71. return strtoull(cp, 0, 16);
  72. }
  73. Map*
  74. attachproc(int pid, int kflag, int corefd, Fhdr *fp)
  75. {
  76. char buf[64], *regs;
  77. int fd;
  78. Map *map;
  79. uvlong n;
  80. int mode;
  81. map = newmap(0, 4);
  82. if (!map)
  83. return 0;
  84. if(kflag) {
  85. regs = "kregs";
  86. mode = OREAD;
  87. } else {
  88. regs = "regs";
  89. mode = ORDWR;
  90. }
  91. if (mach->regsize) {
  92. sprint(buf, "/proc/%d/%s", pid, regs);
  93. fd = open(buf, mode);
  94. if(fd < 0) {
  95. free(map);
  96. return 0;
  97. }
  98. setmap(map, fd, 0, mach->regsize, 0, "regs");
  99. }
  100. if (mach->fpregsize) {
  101. sprint(buf, "/proc/%d/fpregs", pid);
  102. fd = open(buf, mode);
  103. if(fd < 0) {
  104. close(map->seg[0].fd);
  105. free(map);
  106. return 0;
  107. }
  108. setmap(map, fd, mach->regsize, mach->regsize+mach->fpregsize, 0, "fpregs");
  109. }
  110. setmap(map, corefd, fp->txtaddr, fp->txtaddr+fp->txtsz, fp->txtaddr, "text");
  111. if(kflag || fp->dataddr >= mach->utop) {
  112. setmap(map, corefd, fp->dataddr, ~0, fp->dataddr, "data");
  113. return map;
  114. }
  115. n = stacktop(pid);
  116. if (n == 0) {
  117. setmap(map, corefd, fp->dataddr, mach->utop, fp->dataddr, "data");
  118. return map;
  119. }
  120. setmap(map, corefd, fp->dataddr, n, fp->dataddr, "data");
  121. return map;
  122. }
  123. int
  124. findseg(Map *map, char *name)
  125. {
  126. int i;
  127. if (!map)
  128. return -1;
  129. for (i = 0; i < map->nsegs; i++)
  130. if (map->seg[i].inuse && !strcmp(map->seg[i].name, name))
  131. return i;
  132. return -1;
  133. }
  134. void
  135. unusemap(Map *map, int i)
  136. {
  137. if (map != 0 && 0 <= i && i < map->nsegs)
  138. map->seg[i].inuse = 0;
  139. }
  140. Map*
  141. loadmap(Map *map, int fd, Fhdr *fp)
  142. {
  143. map = newmap(map, 2);
  144. if (map == 0)
  145. return 0;
  146. map->seg[0].b = fp->txtaddr;
  147. map->seg[0].e = fp->txtaddr+fp->txtsz;
  148. map->seg[0].f = fp->txtoff;
  149. map->seg[0].fd = fd;
  150. map->seg[0].inuse = 1;
  151. map->seg[0].name = "text";
  152. map->seg[1].b = fp->dataddr;
  153. map->seg[1].e = fp->dataddr+fp->datsz;
  154. map->seg[1].f = fp->datoff;
  155. map->seg[1].fd = fd;
  156. map->seg[1].inuse = 1;
  157. map->seg[1].name = "data";
  158. return map;
  159. }