map.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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 n;
  58. char *cp;
  59. snprint(buf, sizeof(buf), "/proc/%d/segment", pid);
  60. fd = open(buf, 0);
  61. if (fd < 0)
  62. return 0;
  63. n = read(fd, buf, sizeof(buf)-1);
  64. close(fd);
  65. buf[n] = 0;
  66. if (strncmp(buf, "Stack", 5))
  67. return 0;
  68. for (cp = buf+5; *cp && *cp == ' '; cp++)
  69. ;
  70. if (!*cp)
  71. return 0;
  72. cp = strchr(cp, ' ');
  73. if (!cp)
  74. return 0;
  75. while (*cp && *cp == ' ')
  76. cp++;
  77. if (!*cp)
  78. return 0;
  79. return strtoull(cp, 0, 16);
  80. }
  81. Map*
  82. attachproc(int pid, int kflag, int corefd, Fhdr *fp)
  83. {
  84. char buf[64], *regs;
  85. int fd;
  86. Map *map;
  87. uint64_t n;
  88. map = newmap(0, 4);
  89. if (!map)
  90. return 0;
  91. if(kflag)
  92. regs = "kregs";
  93. else
  94. regs = "regs";
  95. if (mach->regsize) {
  96. sprint(buf, "/proc/%d/%s", pid, regs);
  97. fd = open(buf, ORDWR);
  98. if(fd < 0)
  99. fd = open(buf, OREAD);
  100. if(fd < 0) {
  101. free(map);
  102. return 0;
  103. }
  104. setmap(map, fd, 0, mach->regsize, 0, "regs");
  105. }
  106. if (mach->fpregsize) {
  107. sprint(buf, "/proc/%d/fpregs", pid);
  108. fd = open(buf, ORDWR);
  109. if(fd < 0)
  110. fd = open(buf, OREAD);
  111. if(fd < 0) {
  112. close(map->seg[0].fd);
  113. free(map);
  114. return 0;
  115. }
  116. setmap(map, fd, mach->regsize, mach->regsize+mach->fpregsize, 0, "fpregs");
  117. }
  118. setmap(map, corefd, fp->txtaddr, fp->txtaddr+fp->txtsz, fp->txtaddr, "text");
  119. if(kflag || fp->dataddr >= mach->utop) {
  120. setmap(map, corefd, fp->dataddr, ~0, fp->dataddr, "data");
  121. return map;
  122. }
  123. n = stacktop(pid);
  124. if (n == 0) {
  125. setmap(map, corefd, fp->dataddr, mach->utop, fp->dataddr, "data");
  126. return map;
  127. }
  128. setmap(map, corefd, fp->dataddr, n, fp->dataddr, "data");
  129. return map;
  130. }
  131. int
  132. findseg(Map *map, char *name)
  133. {
  134. int i;
  135. if (!map)
  136. return -1;
  137. for (i = 0; i < map->nsegs; i++)
  138. if (map->seg[i].inuse && !strcmp(map->seg[i].name, name))
  139. return i;
  140. return -1;
  141. }
  142. void
  143. unusemap(Map *map, int i)
  144. {
  145. if (map != 0 && 0 <= i && i < map->nsegs)
  146. map->seg[i].inuse = 0;
  147. }
  148. Map*
  149. loadmap(Map *map, int fd, Fhdr *fp)
  150. {
  151. map = newmap(map, 2);
  152. if (map == 0)
  153. return 0;
  154. map->seg[0].b = fp->txtaddr;
  155. map->seg[0].e = fp->txtaddr+fp->txtsz;
  156. map->seg[0].f = fp->txtoff;
  157. map->seg[0].fd = fd;
  158. map->seg[0].inuse = 1;
  159. map->seg[0].name = "text";
  160. map->seg[1].b = fp->dataddr;
  161. map->seg[1].e = fp->dataddr+fp->datsz;
  162. map->seg[1].f = fp->datoff;
  163. map->seg[1].fd = fd;
  164. map->seg[1].inuse = 1;
  165. map->seg[1].name = "data";
  166. return map;
  167. }