read.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include "snap.h"
  5. void
  6. panic(char *s)
  7. {
  8. fprint(2, "%s\n", s);
  9. abort();
  10. exits(s);
  11. }
  12. static Proc*
  13. findpid(Proc *plist, long pid)
  14. {
  15. while(plist) {
  16. if(plist->pid == pid)
  17. break;
  18. plist = plist->link;
  19. }
  20. return plist;
  21. }
  22. Page*
  23. findpage(Proc *plist, long pid, int type, ulong off)
  24. {
  25. Seg *s;
  26. int i;
  27. plist = findpid(plist, pid);
  28. if(plist == nil)
  29. panic("can't find referenced pid");
  30. if(type == 't') {
  31. if(off%Pagesize)
  32. panic("bad text offset alignment");
  33. s = plist->text;
  34. if(off >= s->len)
  35. return nil;
  36. return s->pg[off/Pagesize];
  37. }
  38. s = nil;
  39. for(i=0; i<plist->nseg; i++) {
  40. s = plist->seg[i];
  41. if(s && s->offset <= off && off < s->offset+s->len)
  42. break;
  43. s = nil;
  44. }
  45. if(s == nil)
  46. return nil;
  47. off -= s->offset;
  48. if(off%Pagesize)
  49. panic("bad mem offset alignment");
  50. return s->pg[off/Pagesize];
  51. }
  52. static Data*
  53. readdata(Biobuf *b)
  54. {
  55. Data *d;
  56. char str[32];
  57. long len;
  58. if(Bread(b, str, 12) != 12)
  59. panic("can't read data hdr\n");
  60. len = atoi(str);
  61. d = emalloc(sizeof(*d) + len);
  62. if(Bread(b, d->data, len) != len)
  63. panic("can't read data body\n");
  64. d->len = len;
  65. return d;
  66. }
  67. static Seg*
  68. readseg(Seg **ps, Biobuf *b, Proc *plist)
  69. {
  70. Seg *s;
  71. Page **pp;
  72. int i, npg;
  73. int t;
  74. int len;
  75. ulong pid, off;
  76. char buf[Pagesize];
  77. static char zero[Pagesize];
  78. s = emalloc(sizeof *s);
  79. if(Bread(b, buf, 2*12) != 2*12)
  80. panic("error reading segment");
  81. s->offset = atoi(buf);
  82. s->len = atoi(buf+12);
  83. npg = (s->len + Pagesize-1)/Pagesize;
  84. s->npg = npg;
  85. if(s->npg == 0)
  86. return s;
  87. pp = emalloc(sizeof(*pp)*npg);
  88. s->pg = pp;
  89. *ps = s;
  90. len = Pagesize;
  91. for(i=0; i<npg; i++) {
  92. if(i == npg-1)
  93. len = s->len - i*Pagesize;
  94. switch(t = Bgetc(b)) {
  95. case 'z':
  96. pp[i] = datapage(zero, len);
  97. if(debug)
  98. fprint(2, "0x%.8lux all zeros\n", s->offset+i*Pagesize);
  99. break;
  100. case 'm':
  101. case 't':
  102. if(Bread(b, buf, 2*12) != 2*12)
  103. panic("error reading segment");
  104. pid = atol(buf);
  105. off = atol(buf+12);
  106. pp[i] = findpage(plist, pid, t, off);
  107. if(pp[i] == nil)
  108. panic("bad page reference in snapshot");
  109. if(debug)
  110. fprint(2, "0x%.8lux same as %s pid %lud 0x%.8lux\n", s->offset+i*Pagesize, t=='m'?"mem":"text", pid, off);
  111. break;
  112. case 'r':
  113. if(Bread(b, buf, len) != len)
  114. panic("error reading segment");
  115. pp[i] = datapage(buf, len);
  116. if(debug)
  117. fprint(2, "0x%.8lux is raw data\n", s->offset+i*Pagesize);
  118. break;
  119. default:
  120. panic("error reading segment");
  121. }
  122. }
  123. return s;
  124. }
  125. Proc*
  126. readsnap(Biobuf *b)
  127. {
  128. char *q;
  129. char buf[12];
  130. long pid;
  131. Proc *p, *plist;
  132. int i, n;
  133. if((q = Brdline(b, '\n')) == nil)
  134. panic("error reading snapshot file");
  135. if(strncmp(q, "process snapshot", strlen("process snapshot")) != 0)
  136. panic("bad snapshot file format");
  137. plist = nil;
  138. while(q = Brdline(b, '\n')) {
  139. q[Blinelen(b)-1] = 0;
  140. pid = atol(q);
  141. q += 12;
  142. p = findpid(plist, pid);
  143. if(p == nil) {
  144. p = emalloc(sizeof(*p));
  145. p->link = plist;
  146. p->pid = pid;
  147. plist = p;
  148. }
  149. for(i=0; i<Npfile; i++) {
  150. if(strcmp(pfile[i], q) == 0) {
  151. p->d[i] = readdata(b);
  152. break;
  153. }
  154. }
  155. if(i != Npfile)
  156. continue;
  157. if(strcmp(q, "mem") == 0) {
  158. if(Bread(b, buf, 12) != 12)
  159. panic("can't read memory section");
  160. n = atoi(buf);
  161. p->nseg = n;
  162. p->seg = emalloc(n*sizeof(*p->seg));
  163. for(i=0; i<n; i++)
  164. readseg(&p->seg[i], b, plist);
  165. } else if(strcmp(q, "text") == 0)
  166. readseg(&p->text, b, plist);
  167. else
  168. panic("unknown section");
  169. }
  170. return plist;
  171. }