xref: /plan9/sys/src/libmach/map.c (revision bad30d5d5a5510556b3d04cddb2a7590f26fb546)
13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier  * file map routines
33e12c5d1SDavid du Colombier  */
4bd389b36SDavid du Colombier #include <u.h>
5bd389b36SDavid du Colombier #include <libc.h>
6bd389b36SDavid du Colombier #include <bio.h>
7bd389b36SDavid du Colombier #include <mach.h>
83e12c5d1SDavid du Colombier 
93e12c5d1SDavid du Colombier Map *
newmap(Map * map,int n)107dd7cddfSDavid du Colombier newmap(Map *map, int n)
113e12c5d1SDavid du Colombier {
12219b2ee8SDavid du Colombier 	int size;
13219b2ee8SDavid du Colombier 
14219b2ee8SDavid du Colombier 	size = sizeof(Map)+(n-1)*sizeof(struct segment);
15219b2ee8SDavid du Colombier 	if (map == 0)
16219b2ee8SDavid du Colombier 		map = malloc(size);
17219b2ee8SDavid du Colombier 	else
18219b2ee8SDavid du Colombier 		map = realloc(map, size);
193e12c5d1SDavid du Colombier 	if (map == 0) {
20219b2ee8SDavid du Colombier 		werrstr("out of memory: %r");
213e12c5d1SDavid du Colombier 		return 0;
223e12c5d1SDavid du Colombier 	}
23219b2ee8SDavid du Colombier 	memset(map, 0, size);
24219b2ee8SDavid du Colombier 	map->nsegs = n;
253e12c5d1SDavid du Colombier 	return map;
263e12c5d1SDavid du Colombier }
273e12c5d1SDavid du Colombier 
283e12c5d1SDavid du Colombier int
setmap(Map * map,int fd,uvlong b,uvlong e,vlong f,char * name)294de34a7eSDavid du Colombier setmap(Map *map, int fd, uvlong b, uvlong e, vlong f, char *name)
303e12c5d1SDavid du Colombier {
31219b2ee8SDavid du Colombier 	int i;
32219b2ee8SDavid du Colombier 
33219b2ee8SDavid du Colombier 	if (map == 0)
343e12c5d1SDavid du Colombier 		return 0;
35219b2ee8SDavid du Colombier 	for (i = 0; i < map->nsegs; i++)
36219b2ee8SDavid du Colombier 		if (!map->seg[i].inuse)
37219b2ee8SDavid du Colombier 			break;
38219b2ee8SDavid du Colombier 	if (i >= map->nsegs)
39219b2ee8SDavid du Colombier 		return 0;
40219b2ee8SDavid du Colombier 	map->seg[i].b = b;
41219b2ee8SDavid du Colombier 	map->seg[i].e = e;
42219b2ee8SDavid du Colombier 	map->seg[i].f = f;
43219b2ee8SDavid du Colombier 	map->seg[i].inuse = 1;
44219b2ee8SDavid du Colombier 	map->seg[i].name = name;
457dd7cddfSDavid du Colombier 	map->seg[i].fd = fd;
463e12c5d1SDavid du Colombier 	return 1;
473e12c5d1SDavid du Colombier }
483e12c5d1SDavid du Colombier 
494de34a7eSDavid du Colombier static uvlong
stacktop(int pid)507dd7cddfSDavid du Colombier stacktop(int pid)
517dd7cddfSDavid du Colombier {
527dd7cddfSDavid du Colombier 	char buf[64];
537dd7cddfSDavid du Colombier 	int fd;
547dd7cddfSDavid du Colombier 	int n;
557dd7cddfSDavid du Colombier 	char *cp;
567dd7cddfSDavid du Colombier 
574de34a7eSDavid du Colombier 	snprint(buf, sizeof(buf), "/proc/%d/segment", pid);
587dd7cddfSDavid du Colombier 	fd = open(buf, 0);
597dd7cddfSDavid du Colombier 	if (fd < 0)
607dd7cddfSDavid du Colombier 		return 0;
617dd7cddfSDavid du Colombier 	n = read(fd, buf, sizeof(buf)-1);
627dd7cddfSDavid du Colombier 	close(fd);
637dd7cddfSDavid du Colombier 	buf[n] = 0;
647dd7cddfSDavid du Colombier 	if (strncmp(buf, "Stack", 5))
657dd7cddfSDavid du Colombier 		return 0;
667dd7cddfSDavid du Colombier 	for (cp = buf+5; *cp && *cp == ' '; cp++)
677dd7cddfSDavid du Colombier 		;
687dd7cddfSDavid du Colombier 	if (!*cp)
697dd7cddfSDavid du Colombier 		return 0;
707dd7cddfSDavid du Colombier 	cp = strchr(cp, ' ');
717dd7cddfSDavid du Colombier 	if (!cp)
727dd7cddfSDavid du Colombier 		return 0;
737dd7cddfSDavid du Colombier 	while (*cp && *cp == ' ')
747dd7cddfSDavid du Colombier 		cp++;
757dd7cddfSDavid du Colombier 	if (!*cp)
767dd7cddfSDavid du Colombier 		return 0;
774de34a7eSDavid du Colombier 	return strtoull(cp, 0, 16);
787dd7cddfSDavid du Colombier }
797dd7cddfSDavid du Colombier 
807dd7cddfSDavid du Colombier Map*
attachproc(int pid,int kflag,int corefd,Fhdr * fp)817dd7cddfSDavid du Colombier attachproc(int pid, int kflag, int corefd, Fhdr *fp)
827dd7cddfSDavid du Colombier {
837dd7cddfSDavid du Colombier 	char buf[64], *regs;
847dd7cddfSDavid du Colombier 	int fd;
857dd7cddfSDavid du Colombier 	Map *map;
864de34a7eSDavid du Colombier 	uvlong n;
877dd7cddfSDavid du Colombier 
887dd7cddfSDavid du Colombier 	map = newmap(0, 4);
897dd7cddfSDavid du Colombier 	if (!map)
907dd7cddfSDavid du Colombier 		return 0;
91793f14d2SDavid du Colombier 	if(kflag)
927dd7cddfSDavid du Colombier 		regs = "kregs";
93793f14d2SDavid du Colombier 	else
947dd7cddfSDavid du Colombier 		regs = "regs";
957dd7cddfSDavid du Colombier 	if (mach->regsize) {
967dd7cddfSDavid du Colombier 		sprint(buf, "/proc/%d/%s", pid, regs);
97*bad30d5dSDavid du Colombier 		fd = open(buf, ORDWR);
98*bad30d5dSDavid du Colombier 		if(fd < 0)
99*bad30d5dSDavid du Colombier 			fd = open(buf, OREAD);
1007dd7cddfSDavid du Colombier 		if(fd < 0) {
1017dd7cddfSDavid du Colombier 			free(map);
1027dd7cddfSDavid du Colombier 			return 0;
1037dd7cddfSDavid du Colombier 		}
1047dd7cddfSDavid du Colombier 		setmap(map, fd, 0, mach->regsize, 0, "regs");
1057dd7cddfSDavid du Colombier 	}
1067dd7cddfSDavid du Colombier 	if (mach->fpregsize) {
1077dd7cddfSDavid du Colombier 		sprint(buf, "/proc/%d/fpregs", pid);
108*bad30d5dSDavid du Colombier 		fd = open(buf, ORDWR);
109*bad30d5dSDavid du Colombier 		if(fd < 0)
110*bad30d5dSDavid du Colombier 			fd = open(buf, OREAD);
1117dd7cddfSDavid du Colombier 		if(fd < 0) {
1127dd7cddfSDavid du Colombier 			close(map->seg[0].fd);
1137dd7cddfSDavid du Colombier 			free(map);
1147dd7cddfSDavid du Colombier 			return 0;
1157dd7cddfSDavid du Colombier 		}
1167dd7cddfSDavid du Colombier 		setmap(map, fd, mach->regsize, mach->regsize+mach->fpregsize, 0, "fpregs");
1177dd7cddfSDavid du Colombier 	}
1187dd7cddfSDavid du Colombier 	setmap(map, corefd, fp->txtaddr, fp->txtaddr+fp->txtsz, fp->txtaddr, "text");
1194de34a7eSDavid du Colombier 	if(kflag || fp->dataddr >= mach->utop) {
1204de34a7eSDavid du Colombier 		setmap(map, corefd, fp->dataddr, ~0, fp->dataddr, "data");
1217dd7cddfSDavid du Colombier 		return map;
1227dd7cddfSDavid du Colombier 	}
1237dd7cddfSDavid du Colombier 	n = stacktop(pid);
1247dd7cddfSDavid du Colombier 	if (n == 0) {
1254de34a7eSDavid du Colombier 		setmap(map, corefd, fp->dataddr, mach->utop, fp->dataddr, "data");
1267dd7cddfSDavid du Colombier 		return map;
1277dd7cddfSDavid du Colombier 	}
1287dd7cddfSDavid du Colombier 	setmap(map, corefd, fp->dataddr, n, fp->dataddr, "data");
1297dd7cddfSDavid du Colombier 	return map;
1307dd7cddfSDavid du Colombier }
1317dd7cddfSDavid du Colombier 
132219b2ee8SDavid du Colombier int
findseg(Map * map,char * name)133219b2ee8SDavid du Colombier findseg(Map *map, char *name)
1343e12c5d1SDavid du Colombier {
135219b2ee8SDavid du Colombier 	int i;
136219b2ee8SDavid du Colombier 
137219b2ee8SDavid du Colombier 	if (!map)
138219b2ee8SDavid du Colombier 		return -1;
139219b2ee8SDavid du Colombier 	for (i = 0; i < map->nsegs; i++)
140219b2ee8SDavid du Colombier 		if (map->seg[i].inuse && !strcmp(map->seg[i].name, name))
141219b2ee8SDavid du Colombier 			return i;
142219b2ee8SDavid du Colombier 	return -1;
143219b2ee8SDavid du Colombier }
144219b2ee8SDavid du Colombier 
145219b2ee8SDavid du Colombier void
unusemap(Map * map,int i)146219b2ee8SDavid du Colombier unusemap(Map *map, int i)
147219b2ee8SDavid du Colombier {
148219b2ee8SDavid du Colombier 	if (map != 0 && 0 <= i && i < map->nsegs)
149219b2ee8SDavid du Colombier 		map->seg[i].inuse = 0;
1503e12c5d1SDavid du Colombier }
1513e12c5d1SDavid du Colombier 
1523e12c5d1SDavid du Colombier Map*
loadmap(Map * map,int fd,Fhdr * fp)1533e12c5d1SDavid du Colombier loadmap(Map *map, int fd, Fhdr *fp)
1543e12c5d1SDavid du Colombier {
1557dd7cddfSDavid du Colombier 	map = newmap(map, 2);
1563e12c5d1SDavid du Colombier 	if (map == 0)
1573e12c5d1SDavid du Colombier 		return 0;
1587dd7cddfSDavid du Colombier 
159219b2ee8SDavid du Colombier 	map->seg[0].b = fp->txtaddr;
160219b2ee8SDavid du Colombier 	map->seg[0].e = fp->txtaddr+fp->txtsz;
161219b2ee8SDavid du Colombier 	map->seg[0].f = fp->txtoff;
1627dd7cddfSDavid du Colombier 	map->seg[0].fd = fd;
163219b2ee8SDavid du Colombier 	map->seg[0].inuse = 1;
164219b2ee8SDavid du Colombier 	map->seg[0].name = "text";
165219b2ee8SDavid du Colombier 	map->seg[1].b = fp->dataddr;
166219b2ee8SDavid du Colombier 	map->seg[1].e = fp->dataddr+fp->datsz;
167219b2ee8SDavid du Colombier 	map->seg[1].f = fp->datoff;
1687dd7cddfSDavid du Colombier 	map->seg[1].fd = fd;
169219b2ee8SDavid du Colombier 	map->seg[1].inuse = 1;
170219b2ee8SDavid du Colombier 	map->seg[1].name = "data";
1713e12c5d1SDavid du Colombier 	return map;
1723e12c5d1SDavid du Colombier }
173