map.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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. else
  87. regs = "regs";
  88. mode = ORDWR;
  89. if (mach->regsize) {
  90. sprint(buf, "/proc/%d/%s", pid, regs);
  91. fd = open(buf, mode);
  92. if(fd < 0) {
  93. free(map);
  94. return 0;
  95. }
  96. setmap(map, fd, 0, mach->regsize, 0, "regs");
  97. }
  98. if (mach->fpregsize) {
  99. sprint(buf, "/proc/%d/fpregs", pid);
  100. fd = open(buf, mode);
  101. if(fd < 0) {
  102. close(map->seg[0].fd);
  103. free(map);
  104. return 0;
  105. }
  106. setmap(map, fd, mach->regsize, mach->regsize+mach->fpregsize, 0, "fpregs");
  107. }
  108. setmap(map, corefd, fp->txtaddr, fp->txtaddr+fp->txtsz, fp->txtaddr, "text");
  109. if(kflag || fp->dataddr >= mach->utop) {
  110. setmap(map, corefd, fp->dataddr, ~0, fp->dataddr, "data");
  111. return map;
  112. }
  113. n = stacktop(pid);
  114. if (n == 0) {
  115. setmap(map, corefd, fp->dataddr, mach->utop, fp->dataddr, "data");
  116. return map;
  117. }
  118. setmap(map, corefd, fp->dataddr, n, fp->dataddr, "data");
  119. return map;
  120. }
  121. int
  122. findseg(Map *map, char *name)
  123. {
  124. int i;
  125. if (!map)
  126. return -1;
  127. for (i = 0; i < map->nsegs; i++)
  128. if (map->seg[i].inuse && !strcmp(map->seg[i].name, name))
  129. return i;
  130. return -1;
  131. }
  132. void
  133. unusemap(Map *map, int i)
  134. {
  135. if (map != 0 && 0 <= i && i < map->nsegs)
  136. map->seg[i].inuse = 0;
  137. }
  138. Map*
  139. loadmap(Map *map, int fd, Fhdr *fp)
  140. {
  141. map = newmap(map, 2);
  142. if (map == 0)
  143. return 0;
  144. map->seg[0].b = fp->txtaddr;
  145. map->seg[0].e = fp->txtaddr+fp->txtsz;
  146. map->seg[0].f = fp->txtoff;
  147. map->seg[0].fd = fd;
  148. map->seg[0].inuse = 1;
  149. map->seg[0].name = "text";
  150. map->seg[1].b = fp->dataddr;
  151. map->seg[1].e = fp->dataddr+fp->datsz;
  152. map->seg[1].f = fp->datoff;
  153. map->seg[1].fd = fd;
  154. map->seg[1].inuse = 1;
  155. map->seg[1].name = "data";
  156. return map;
  157. }