123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- /*
- * file map routines
- */
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- #include <mach.h>
- Map *
- newmap(Map *map, int n)
- {
- int size;
- size = sizeof(Map)+(n-1)*sizeof(struct segment);
- if (map == 0)
- map = malloc(size);
- else
- map = realloc(map, size);
- if (map == 0) {
- werrstr("out of memory: %r");
- return 0;
- }
- memset(map, 0, size);
- map->nsegs = n;
- return map;
- }
- int
- setmap(Map *map, int fd, uint64_t b, uint64_t e, int64_t f, char *name)
- {
- int i;
- if (map == 0)
- return 0;
- for (i = 0; i < map->nsegs; i++)
- if (!map->seg[i].inuse)
- break;
- if (i >= map->nsegs)
- return 0;
- map->seg[i].b = b;
- map->seg[i].e = e;
- map->seg[i].f = f;
- map->seg[i].inuse = 1;
- map->seg[i].name = name;
- map->seg[i].fd = fd;
- return 1;
- }
- static uint64_t
- stacktop(int pid)
- {
- char buf[64];
- int fd;
- int n;
- char *cp;
- snprint(buf, sizeof(buf), "/proc/%d/segment", pid);
- fd = open(buf, 0);
- if (fd < 0)
- return 0;
- n = read(fd, buf, sizeof(buf)-1);
- close(fd);
- buf[n] = 0;
- if (strncmp(buf, "Stack", 5))
- return 0;
- for (cp = buf+5; *cp && *cp == ' '; cp++)
- ;
- if (!*cp)
- return 0;
- cp = strchr(cp, ' ');
- if (!cp)
- return 0;
- while (*cp && *cp == ' ')
- cp++;
- if (!*cp)
- return 0;
- return strtoull(cp, 0, 16);
- }
- Map*
- attachproc(int pid, int kflag, int corefd, Fhdr *fp)
- {
- char buf[64], *regs;
- int fd;
- Map *map;
- uint64_t n;
- map = newmap(0, 4);
- if (!map)
- return 0;
- if(kflag)
- regs = "kregs";
- else
- regs = "regs";
- if (mach->regsize) {
- sprint(buf, "/proc/%d/%s", pid, regs);
- fd = open(buf, ORDWR);
- if(fd < 0)
- fd = open(buf, OREAD);
- if(fd < 0) {
- free(map);
- return 0;
- }
- setmap(map, fd, 0, mach->regsize, 0, "regs");
- }
- if (mach->fpregsize) {
- sprint(buf, "/proc/%d/fpregs", pid);
- fd = open(buf, ORDWR);
- if(fd < 0)
- fd = open(buf, OREAD);
- if(fd < 0) {
- close(map->seg[0].fd);
- free(map);
- return 0;
- }
- setmap(map, fd, mach->regsize, mach->regsize+mach->fpregsize, 0, "fpregs");
- }
- setmap(map, corefd, fp->txtaddr, fp->txtaddr+fp->txtsz, fp->txtaddr, "text");
- if(kflag || fp->dataddr >= mach->utop) {
- setmap(map, corefd, fp->dataddr, ~0, fp->dataddr, "data");
- return map;
- }
- n = stacktop(pid);
- if (n == 0) {
- setmap(map, corefd, fp->dataddr, mach->utop, fp->dataddr, "data");
- return map;
- }
- setmap(map, corefd, fp->dataddr, n, fp->dataddr, "data");
- return map;
- }
-
- int
- findseg(Map *map, char *name)
- {
- int i;
- if (!map)
- return -1;
- for (i = 0; i < map->nsegs; i++)
- if (map->seg[i].inuse && !strcmp(map->seg[i].name, name))
- return i;
- return -1;
- }
- void
- unusemap(Map *map, int i)
- {
- if (map != 0 && 0 <= i && i < map->nsegs)
- map->seg[i].inuse = 0;
- }
- Map*
- loadmap(Map *map, int fd, Fhdr *fp)
- {
- map = newmap(map, 2);
- if (map == 0)
- return 0;
- map->seg[0].b = fp->txtaddr;
- map->seg[0].e = fp->txtaddr+fp->txtsz;
- map->seg[0].f = fp->txtoff;
- map->seg[0].fd = fd;
- map->seg[0].inuse = 1;
- map->seg[0].name = "text";
- map->seg[1].b = fp->dataddr;
- map->seg[1].e = fp->dataddr+fp->datsz;
- map->seg[1].f = fp->datoff;
- map->seg[1].fd = fd;
- map->seg[1].inuse = 1;
- map->seg[1].name = "data";
- return map;
- }
|