map.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. /*
  10. * file map routines
  11. */
  12. #include <u.h>
  13. #include <libc.h>
  14. #include <bio.h>
  15. #include <mach.h>
  16. Map *
  17. newmap(Map *map, int n)
  18. {
  19. int size;
  20. size = sizeof(Map)+(n-1)*sizeof(struct segment);
  21. if (map == 0)
  22. map = malloc(size);
  23. else
  24. map = realloc(map, size);
  25. if (map == 0) {
  26. werrstr("out of memory: %r");
  27. return 0;
  28. }
  29. memset(map, 0, size);
  30. map->nsegs = n;
  31. return map;
  32. }
  33. int
  34. setmap(Map *map, int fd, uint64_t b, uint64_t e, int64_t f, char *name)
  35. {
  36. int i;
  37. if (map == 0)
  38. return 0;
  39. for (i = 0; i < map->nsegs; i++)
  40. if (!map->seg[i].inuse)
  41. break;
  42. if (i >= map->nsegs)
  43. return 0;
  44. map->seg[i].b = b;
  45. map->seg[i].e = e;
  46. map->seg[i].f = f;
  47. map->seg[i].inuse = 1;
  48. map->seg[i].name = name;
  49. map->seg[i].fd = fd;
  50. return 1;
  51. }
  52. static uint64_t
  53. stacktop(int pid)
  54. {
  55. char buf[64];
  56. int fd;
  57. int i, n;
  58. char *cp;
  59. // Gets the stack segment details by parsing the first line of
  60. // /proc/pid/segment, assuming it'll be 'Stack'.
  61. // This line will be of the form:
  62. // Stack rw- 7ffffee00000 7fffffe00000 1
  63. // We need to get the 4th token - the top of the stack.
  64. snprint(buf, sizeof(buf), "/proc/%d/segment", pid);
  65. fd = open(buf, 0);
  66. if (fd < 0)
  67. return 0;
  68. n = read(fd, buf, sizeof(buf)-1);
  69. close(fd);
  70. buf[n] = 0;
  71. if (strncmp(buf, "Stack", 5))
  72. return 0;
  73. for (i = 0, cp = buf; i < 3; i++) {
  74. // Skip over the token to the next space
  75. cp = strchr(cp, ' ');
  76. if (!cp)
  77. return 0;
  78. // Skip over spaces
  79. while (*cp == ' ')
  80. cp++;
  81. if (!*cp)
  82. return 0;
  83. }
  84. // cp now points to the token representing the end of the stack,
  85. // so parse and return it.
  86. return strtoull(cp, 0, 16);
  87. }
  88. Map*
  89. attachproc(int pid, int kflag, int corefd, Fhdr *fp)
  90. {
  91. char buf[64], *regs;
  92. int fd;
  93. Map *map;
  94. uint64_t n;
  95. map = newmap(0, 4);
  96. if (!map)
  97. return 0;
  98. if(kflag)
  99. regs = "kregs";
  100. else
  101. regs = "regs";
  102. if (mach->regsize) {
  103. sprint(buf, "/proc/%d/%s", pid, regs);
  104. fd = open(buf, ORDWR);
  105. if(fd < 0)
  106. fd = open(buf, OREAD);
  107. if(fd < 0) {
  108. free(map);
  109. return 0;
  110. }
  111. setmap(map, fd, 0, mach->regsize, 0, "regs");
  112. }
  113. if (mach->fpregsize) {
  114. sprint(buf, "/proc/%d/fpregs", pid);
  115. fd = open(buf, ORDWR);
  116. if(fd < 0)
  117. fd = open(buf, OREAD);
  118. if(fd < 0) {
  119. close(map->seg[0].fd);
  120. free(map);
  121. return 0;
  122. }
  123. setmap(map, fd, mach->regsize, mach->regsize+mach->fpregsize, 0, "fpregs");
  124. }
  125. setmap(map, corefd, fp->txtaddr, fp->txtaddr+fp->txtsz, fp->txtaddr, "text");
  126. if(kflag || fp->dataddr >= mach->utop) {
  127. setmap(map, corefd, fp->dataddr, ~0, fp->dataddr, "data");
  128. return map;
  129. }
  130. n = stacktop(pid);
  131. if (n == 0) {
  132. setmap(map, corefd, fp->dataddr, mach->utop, fp->dataddr, "data");
  133. return map;
  134. }
  135. setmap(map, corefd, fp->dataddr, n, fp->dataddr, "data");
  136. return map;
  137. }
  138. int
  139. findseg(Map *map, char *name)
  140. {
  141. int i;
  142. if (!map)
  143. return -1;
  144. for (i = 0; i < map->nsegs; i++)
  145. if (map->seg[i].inuse && !strcmp(map->seg[i].name, name))
  146. return i;
  147. return -1;
  148. }
  149. void
  150. unusemap(Map *map, int i)
  151. {
  152. if (map != 0 && 0 <= i && i < map->nsegs)
  153. map->seg[i].inuse = 0;
  154. }
  155. Map*
  156. loadmap(Map *map, int fd, Fhdr *fp)
  157. {
  158. map = newmap(map, 2);
  159. if (map == 0)
  160. return 0;
  161. map->seg[0].b = fp->txtaddr;
  162. map->seg[0].e = fp->txtaddr+fp->txtsz;
  163. map->seg[0].f = fp->txtoff;
  164. map->seg[0].fd = fd;
  165. map->seg[0].inuse = 1;
  166. map->seg[0].name = "text";
  167. map->seg[1].b = fp->dataddr;
  168. map->seg[1].e = fp->dataddr+fp->datsz;
  169. map->seg[1].f = fp->datoff;
  170. map->seg[1].fd = fd;
  171. map->seg[1].inuse = 1;
  172. map->seg[1].name = "data";
  173. return map;
  174. }