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