174a4d8c2SCharles.Forsyth /*
274a4d8c2SCharles.Forsyth * file map routines
374a4d8c2SCharles.Forsyth */
474a4d8c2SCharles.Forsyth #include <lib9.h>
574a4d8c2SCharles.Forsyth #include <bio.h>
674a4d8c2SCharles.Forsyth #include "mach.h"
774a4d8c2SCharles.Forsyth
874a4d8c2SCharles.Forsyth Map *
newmap(Map * map,int n)974a4d8c2SCharles.Forsyth newmap(Map *map, int n)
1074a4d8c2SCharles.Forsyth {
1174a4d8c2SCharles.Forsyth int size;
1274a4d8c2SCharles.Forsyth
1374a4d8c2SCharles.Forsyth size = sizeof(Map)+(n-1)*sizeof(struct segment);
1474a4d8c2SCharles.Forsyth if (map == 0)
1574a4d8c2SCharles.Forsyth map = malloc(size);
1674a4d8c2SCharles.Forsyth else
1774a4d8c2SCharles.Forsyth map = realloc(map, size);
1874a4d8c2SCharles.Forsyth if (map == 0) {
1974a4d8c2SCharles.Forsyth werrstr("out of memory: %r");
2074a4d8c2SCharles.Forsyth return 0;
2174a4d8c2SCharles.Forsyth }
2274a4d8c2SCharles.Forsyth memset(map, 0, size);
2374a4d8c2SCharles.Forsyth map->nsegs = n;
2474a4d8c2SCharles.Forsyth return map;
2574a4d8c2SCharles.Forsyth }
2674a4d8c2SCharles.Forsyth
2774a4d8c2SCharles.Forsyth int
setmap(Map * map,int fd,uvlong b,uvlong e,vlong f,char * name)28d67b7dadSforsyth setmap(Map *map, int fd, uvlong b, uvlong e, vlong f, char *name)
2974a4d8c2SCharles.Forsyth {
3074a4d8c2SCharles.Forsyth int i;
3174a4d8c2SCharles.Forsyth
3274a4d8c2SCharles.Forsyth if (map == 0)
3374a4d8c2SCharles.Forsyth return 0;
3474a4d8c2SCharles.Forsyth for (i = 0; i < map->nsegs; i++)
3574a4d8c2SCharles.Forsyth if (!map->seg[i].inuse)
3674a4d8c2SCharles.Forsyth break;
3774a4d8c2SCharles.Forsyth if (i >= map->nsegs)
3874a4d8c2SCharles.Forsyth return 0;
3974a4d8c2SCharles.Forsyth map->seg[i].b = b;
4074a4d8c2SCharles.Forsyth map->seg[i].e = e;
4174a4d8c2SCharles.Forsyth map->seg[i].f = f;
4274a4d8c2SCharles.Forsyth map->seg[i].inuse = 1;
4374a4d8c2SCharles.Forsyth map->seg[i].name = name;
4474a4d8c2SCharles.Forsyth map->seg[i].fd = fd;
4574a4d8c2SCharles.Forsyth return 1;
4674a4d8c2SCharles.Forsyth }
4774a4d8c2SCharles.Forsyth
48d67b7dadSforsyth static uvlong
stacktop(int pid)4974a4d8c2SCharles.Forsyth stacktop(int pid)
5074a4d8c2SCharles.Forsyth {
5174a4d8c2SCharles.Forsyth char buf[64];
5274a4d8c2SCharles.Forsyth int fd;
5374a4d8c2SCharles.Forsyth int n;
5474a4d8c2SCharles.Forsyth char *cp;
5574a4d8c2SCharles.Forsyth
56d67b7dadSforsyth snprint(buf, sizeof(buf), "/proc/%d/segment", pid);
5774a4d8c2SCharles.Forsyth fd = open(buf, 0);
5874a4d8c2SCharles.Forsyth if (fd < 0)
5974a4d8c2SCharles.Forsyth return 0;
6074a4d8c2SCharles.Forsyth n = read(fd, buf, sizeof(buf)-1);
6174a4d8c2SCharles.Forsyth close(fd);
6274a4d8c2SCharles.Forsyth buf[n] = 0;
6374a4d8c2SCharles.Forsyth if (strncmp(buf, "Stack", 5))
6474a4d8c2SCharles.Forsyth return 0;
6574a4d8c2SCharles.Forsyth for (cp = buf+5; *cp && *cp == ' '; cp++)
6674a4d8c2SCharles.Forsyth ;
6774a4d8c2SCharles.Forsyth if (!*cp)
6874a4d8c2SCharles.Forsyth return 0;
6974a4d8c2SCharles.Forsyth cp = strchr(cp, ' ');
7074a4d8c2SCharles.Forsyth if (!cp)
7174a4d8c2SCharles.Forsyth return 0;
7274a4d8c2SCharles.Forsyth while (*cp && *cp == ' ')
7374a4d8c2SCharles.Forsyth cp++;
7474a4d8c2SCharles.Forsyth if (!*cp)
7574a4d8c2SCharles.Forsyth return 0;
76d67b7dadSforsyth return strtoull(cp, 0, 16);
7774a4d8c2SCharles.Forsyth }
7874a4d8c2SCharles.Forsyth
7974a4d8c2SCharles.Forsyth Map*
attachproc(int pid,int kflag,int corefd,Fhdr * fp)8074a4d8c2SCharles.Forsyth attachproc(int pid, int kflag, int corefd, Fhdr *fp)
8174a4d8c2SCharles.Forsyth {
8274a4d8c2SCharles.Forsyth char buf[64], *regs;
8374a4d8c2SCharles.Forsyth int fd;
8474a4d8c2SCharles.Forsyth Map *map;
85d67b7dadSforsyth uvlong n;
8674a4d8c2SCharles.Forsyth
8774a4d8c2SCharles.Forsyth map = newmap(0, 4);
8874a4d8c2SCharles.Forsyth if (!map)
8974a4d8c2SCharles.Forsyth return 0;
90*45a20ab7Sforsyth if(kflag)
9174a4d8c2SCharles.Forsyth regs = "kregs";
92*45a20ab7Sforsyth else
9374a4d8c2SCharles.Forsyth regs = "regs";
9474a4d8c2SCharles.Forsyth if (mach->regsize) {
9574a4d8c2SCharles.Forsyth sprint(buf, "/proc/%d/%s", pid, regs);
96*45a20ab7Sforsyth fd = open(buf, ORDWR);
97*45a20ab7Sforsyth if(fd < 0)
98*45a20ab7Sforsyth fd = open(buf, OREAD);
9974a4d8c2SCharles.Forsyth if(fd < 0) {
10074a4d8c2SCharles.Forsyth free(map);
10174a4d8c2SCharles.Forsyth return 0;
10274a4d8c2SCharles.Forsyth }
10374a4d8c2SCharles.Forsyth setmap(map, fd, 0, mach->regsize, 0, "regs");
10474a4d8c2SCharles.Forsyth }
10574a4d8c2SCharles.Forsyth if (mach->fpregsize) {
10674a4d8c2SCharles.Forsyth sprint(buf, "/proc/%d/fpregs", pid);
107*45a20ab7Sforsyth fd = open(buf, ORDWR);
108*45a20ab7Sforsyth if(fd < 0)
109*45a20ab7Sforsyth fd = open(buf, OREAD);
11074a4d8c2SCharles.Forsyth if(fd < 0) {
11174a4d8c2SCharles.Forsyth close(map->seg[0].fd);
11274a4d8c2SCharles.Forsyth free(map);
11374a4d8c2SCharles.Forsyth return 0;
11474a4d8c2SCharles.Forsyth }
11574a4d8c2SCharles.Forsyth setmap(map, fd, mach->regsize, mach->regsize+mach->fpregsize, 0, "fpregs");
11674a4d8c2SCharles.Forsyth }
11774a4d8c2SCharles.Forsyth setmap(map, corefd, fp->txtaddr, fp->txtaddr+fp->txtsz, fp->txtaddr, "text");
118d67b7dadSforsyth if(kflag || fp->dataddr >= mach->utop) {
119d67b7dadSforsyth setmap(map, corefd, fp->dataddr, ~0, fp->dataddr, "data");
12074a4d8c2SCharles.Forsyth return map;
12174a4d8c2SCharles.Forsyth }
12274a4d8c2SCharles.Forsyth n = stacktop(pid);
12374a4d8c2SCharles.Forsyth if (n == 0) {
124d67b7dadSforsyth setmap(map, corefd, fp->dataddr, mach->utop, fp->dataddr, "data");
12574a4d8c2SCharles.Forsyth return map;
12674a4d8c2SCharles.Forsyth }
12774a4d8c2SCharles.Forsyth setmap(map, corefd, fp->dataddr, n, fp->dataddr, "data");
12874a4d8c2SCharles.Forsyth return map;
12974a4d8c2SCharles.Forsyth }
13074a4d8c2SCharles.Forsyth
13174a4d8c2SCharles.Forsyth int
findseg(Map * map,char * name)13274a4d8c2SCharles.Forsyth findseg(Map *map, char *name)
13374a4d8c2SCharles.Forsyth {
13474a4d8c2SCharles.Forsyth int i;
13574a4d8c2SCharles.Forsyth
13674a4d8c2SCharles.Forsyth if (!map)
13774a4d8c2SCharles.Forsyth return -1;
13874a4d8c2SCharles.Forsyth for (i = 0; i < map->nsegs; i++)
13974a4d8c2SCharles.Forsyth if (map->seg[i].inuse && !strcmp(map->seg[i].name, name))
14074a4d8c2SCharles.Forsyth return i;
14174a4d8c2SCharles.Forsyth return -1;
14274a4d8c2SCharles.Forsyth }
14374a4d8c2SCharles.Forsyth
14474a4d8c2SCharles.Forsyth void
unusemap(Map * map,int i)14574a4d8c2SCharles.Forsyth unusemap(Map *map, int i)
14674a4d8c2SCharles.Forsyth {
14774a4d8c2SCharles.Forsyth if (map != 0 && 0 <= i && i < map->nsegs)
14874a4d8c2SCharles.Forsyth map->seg[i].inuse = 0;
14974a4d8c2SCharles.Forsyth }
15074a4d8c2SCharles.Forsyth
15174a4d8c2SCharles.Forsyth Map*
loadmap(Map * map,int fd,Fhdr * fp)152d67b7dadSforsyth loadmap(Map *map, int fd, Fhdr *fp)
153d67b7dadSforsyth {
154d67b7dadSforsyth map = newmap(map, 2);
155d67b7dadSforsyth if (map == 0)
156d67b7dadSforsyth return 0;
157d67b7dadSforsyth
158d67b7dadSforsyth map->seg[0].b = fp->txtaddr;
159d67b7dadSforsyth map->seg[0].e = fp->txtaddr+fp->txtsz;
160d67b7dadSforsyth map->seg[0].f = fp->txtoff;
161d67b7dadSforsyth map->seg[0].fd = fd;
162d67b7dadSforsyth map->seg[0].inuse = 1;
163d67b7dadSforsyth map->seg[0].name = "text";
164d67b7dadSforsyth map->seg[1].b = fp->dataddr;
165d67b7dadSforsyth map->seg[1].e = fp->dataddr+fp->datsz;
166d67b7dadSforsyth map->seg[1].f = fp->datoff;
167d67b7dadSforsyth map->seg[1].fd = fd;
168d67b7dadSforsyth map->seg[1].inuse = 1;
169d67b7dadSforsyth map->seg[1].name = "data";
170d67b7dadSforsyth return map;
171d67b7dadSforsyth }
172d67b7dadSforsyth
173d67b7dadSforsyth Map*
attachremt(int fd,Fhdr * f)17474a4d8c2SCharles.Forsyth attachremt(int fd, Fhdr *f)
17574a4d8c2SCharles.Forsyth {
17674a4d8c2SCharles.Forsyth Map *m;
17774a4d8c2SCharles.Forsyth ulong txt;
17874a4d8c2SCharles.Forsyth
17974a4d8c2SCharles.Forsyth m = newmap(0, 3);
18074a4d8c2SCharles.Forsyth if (m == 0)
18174a4d8c2SCharles.Forsyth return 0;
18274a4d8c2SCharles.Forsyth
18374a4d8c2SCharles.Forsyth /* Space for mach structures */
18474a4d8c2SCharles.Forsyth txt = f->txtaddr;
18574a4d8c2SCharles.Forsyth if(txt > 8*4096)
18674a4d8c2SCharles.Forsyth txt -= 8*4096;
18774a4d8c2SCharles.Forsyth
18874a4d8c2SCharles.Forsyth setmap(m, fd, txt, f->txtaddr+f->txtsz, txt, "*text");
18974a4d8c2SCharles.Forsyth /*setmap(m, fd, f->dataddr, 0xffffffff, f->dataddr, "*data");*/ /* pc heap is < KTZERO */
19074a4d8c2SCharles.Forsyth setmap(m, fd, 4096, 0xffffffff, 4096, "*data");
19174a4d8c2SCharles.Forsyth setmap(m, fd, 0x0, mach->regsize, 0, "kreg");
19274a4d8c2SCharles.Forsyth
19374a4d8c2SCharles.Forsyth return m;
19474a4d8c2SCharles.Forsyth }
19574a4d8c2SCharles.Forsyth
19674a4d8c2SCharles.Forsyth void
setmapio(Map * map,int i,Rsegio get,Rsegio put)19774a4d8c2SCharles.Forsyth setmapio(Map *map, int i, Rsegio get, Rsegio put)
19874a4d8c2SCharles.Forsyth {
19974a4d8c2SCharles.Forsyth if (map != 0 && 0 <= i && i < map->nsegs) {
20074a4d8c2SCharles.Forsyth map->seg[i].mget = get;
20174a4d8c2SCharles.Forsyth map->seg[i].mput = put;
20274a4d8c2SCharles.Forsyth }
20374a4d8c2SCharles.Forsyth }
204