7 /* research 16-bit crc. good enough. */
9 sumr(ulong sum, void *buf, int n)
15 for(s=buf, send=s+n; s<send; s++)
17 sum = 0xffff & ((sum>>1)+*s+0x8000);
19 sum = 0xffff & ((sum>>1)+*s);
25 static Page *pgtab[1<<10];
28 datapage(char *p, long len)
34 sysfatal("datapage cannot handle pages > %d", Pagesize);
36 sum = sumr(0, p, len) & (nelem(pgtab)-1);
37 for(pg = pgtab[sum]; pg != nil; pg=pg->link)
38 if(pg->len == len && memcmp(pg->data, p, len) == 0)
41 pg = emalloc(sizeof(*pg)+len);
42 pg->data = (char*)&pg[1];
45 memmove(pg->data, p, len);
46 if(sum == 0 && memcmp(zeros, p, len) == 0) {
50 pg->link = pgtab[sum];
58 readsection(long pid, char *sec)
65 snprint(buf, sizeof buf, "/proc/%ld/%s", pid, sec);
66 if((fd = open(buf, OREAD)) < 0)
70 hdr = (int)((Data*)0)->data;
71 while((n = read(fd, buf, sizeof buf)) > 0) {
72 d = erealloc(d, tot+n+hdr);
73 memmove(d->data+tot, buf, n);
84 readseg(int fd, uvlong off, uvlong len, char *name)
93 fprint(2, "readseg %.8llux - %.8llux %s\n", off, off+len, name);
95 s = emalloc(sizeof(*s));
96 s->name = estrdup(name);
97 if(seek(fd, off, 0) < 0) {
98 fprint(2, "seek fails\n");
109 if((n = readn(fd, buf, n)) <= 0)
112 if((npg & (npg-1)) == 0)
113 pg = erealloc(pg, sizeof(*pg) * (npg==0 | npg*2));
114 pg[npg++] = datapage(buf, n);
115 if(n != Pagesize) /* any short read, planned or otherwise */
118 if(s->len==0 && len!=0){
122 pg = erealloc(pg, sizeof(*pg) * npg);
132 /* discover the stack pointer of the given process */
134 stackptr(Proc *proc, int fd)
144 for(i=0; i<proc->nseg; i++)
145 if(proc->seg[i] && strcmp(proc->seg[i]->name, "Text") == 0)
146 textoff = proc->seg[i]->offset;
151 if(seek(fd, textoff, 0) < 0)
154 if(crackhdr(fd, &f) == 0)
158 for(r=mach->reglist; r->rname; r++)
159 if(strcmp(r->rname, mach->sp) == 0)
162 fprint(2, "couldn't find stack pointer register?\n");
166 if((dreg = proc->d[Pregs]) == nil)
169 if(r->roffs+mach->szaddr > dreg->len) {
170 fprint(2, "SP register too far into registers?\n");
174 q = dreg->data+r->roffs;
175 switch(mach->szaddr) {
176 case 4: return machdata->swal(*(ulong*)q);
177 case 8: return machdata->swav(*(uvlong*)q);
179 fprint(2, "address size is %d bytes?\n", mach->szaddr);
185 snap(long pid, int usetext)
190 char *name, *segdat, *q, *f[128+1], buf[128];
191 int fd, i, stacki, nf, np;
192 uvlong off, len, stackoff, stacklen, sp;
194 proc = emalloc(sizeof(*proc));
198 for(i=0; i<Npfile; i++) {
199 if(proc->d[i] = readsection(pid, pfile[i]))
202 fprint(2, "warning: can't include /proc/%ld/%s\n", pid, pfile[i]);
208 snprint(buf, sizeof buf, "/proc/%ld/text", pid);
209 if((fd = open(buf, OREAD)) >= 0) {
211 if((proc->text = readseg(fd, 0, 1<<31, "textfile")) == nil)
212 fprint(2, "warning: can't include %s: %r\n", buf);
215 fprint(2, "warning: can't include /proc/%ld/text\n", pid);
218 if((d=proc->d[Psegment]) == nil) {
219 fprint(2, "warning: no segment table, no memory image\n");
223 segdat = emalloc(d->len+1);
224 memmove(segdat, d->data, d->len);
227 nf = getfields(segdat, f, nelem(f), 1, "\n");
230 fprint(2, "process %ld has >%d segments; only using first %d\n",
234 fprint(2, "warning: couldn't understand segment table, no memory image\n");
239 snprint(buf, sizeof buf, "/proc/%ld/mem", pid);
240 if((fd = open(buf, OREAD)) < 0) {
241 fprint(2, "warning: can't include /proc/%ld/mem\n", pid);
245 s = emalloc(nf*sizeof(*s));
249 for(i=0; i<nf; i++) {
250 if(q = strchr(f[i], ' '))
253 off = strtoull(name+10, &q, 16);
254 len = strtoull(q, &q, 16) - off;
255 if(strcmp(name, "Stack") == 0) {
260 s[i] = readseg(fd, off, len, name);
265 /* stack hack: figure sp so don't need to page in the whole segment */
267 sp = stackptr(proc, fd);
269 fprint(2, "stackseg %.8llux - %.8llux sp %.8llux\n",
270 stackoff, stackoff+stacklen, sp);
271 if(stackoff <= sp && sp < stackoff+stacklen) {
273 } else { /* stack pointer not in segment. thread library? */
274 off = stackoff + stacklen - 16*1024;
276 off &= ~((uvlong)Pagesize-1);
279 len = stacklen - (off - stackoff);
280 s[stacki] = readseg(fd, off, len, "Stack");