xref: /inferno-os/utils/libmach/map.c (revision 45a20ab721a513710138340faff3d59a31c3e01e)
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