1 /* 2 * file map routines 3 */ 4 #include <u.h> 5 #include <libc.h> 6 #include <bio.h> 7 #include <mach.h> 8 9 Map * 10 newmap(Map *map, int n) 11 { 12 int size; 13 14 size = sizeof(Map)+(n-1)*sizeof(struct segment); 15 if (map == 0) 16 map = malloc(size); 17 else 18 map = realloc(map, size); 19 if (map == 0) { 20 werrstr("out of memory: %r"); 21 return 0; 22 } 23 memset(map, 0, size); 24 map->nsegs = n; 25 return map; 26 } 27 28 int 29 setmap(Map *map, int fd, uvlong b, uvlong e, vlong f, char *name) 30 { 31 int i; 32 33 if (map == 0) 34 return 0; 35 for (i = 0; i < map->nsegs; i++) 36 if (!map->seg[i].inuse) 37 break; 38 if (i >= map->nsegs) 39 return 0; 40 map->seg[i].b = b; 41 map->seg[i].e = e; 42 map->seg[i].f = f; 43 map->seg[i].inuse = 1; 44 map->seg[i].name = name; 45 map->seg[i].fd = fd; 46 return 1; 47 } 48 49 static uvlong 50 stacktop(int pid) 51 { 52 char buf[64]; 53 int fd; 54 int n; 55 char *cp; 56 57 snprint(buf, sizeof(buf), "/proc/%d/segment", pid); 58 fd = open(buf, 0); 59 if (fd < 0) 60 return 0; 61 n = read(fd, buf, sizeof(buf)-1); 62 close(fd); 63 buf[n] = 0; 64 if (strncmp(buf, "Stack", 5)) 65 return 0; 66 for (cp = buf+5; *cp && *cp == ' '; cp++) 67 ; 68 if (!*cp) 69 return 0; 70 cp = strchr(cp, ' '); 71 if (!cp) 72 return 0; 73 while (*cp && *cp == ' ') 74 cp++; 75 if (!*cp) 76 return 0; 77 return strtoull(cp, 0, 16); 78 } 79 80 Map* 81 attachproc(int pid, int kflag, int corefd, Fhdr *fp) 82 { 83 char buf[64], *regs; 84 int fd; 85 Map *map; 86 uvlong n; 87 88 map = newmap(0, 4); 89 if (!map) 90 return 0; 91 if(kflag) 92 regs = "kregs"; 93 else 94 regs = "regs"; 95 if (mach->regsize) { 96 sprint(buf, "/proc/%d/%s", pid, regs); 97 fd = open(buf, ORDWR); 98 if(fd < 0) 99 fd = open(buf, OREAD); 100 if(fd < 0) { 101 free(map); 102 return 0; 103 } 104 setmap(map, fd, 0, mach->regsize, 0, "regs"); 105 } 106 if (mach->fpregsize) { 107 sprint(buf, "/proc/%d/fpregs", pid); 108 fd = open(buf, ORDWR); 109 if(fd < 0) 110 fd = open(buf, OREAD); 111 if(fd < 0) { 112 close(map->seg[0].fd); 113 free(map); 114 return 0; 115 } 116 setmap(map, fd, mach->regsize, mach->regsize+mach->fpregsize, 0, "fpregs"); 117 } 118 setmap(map, corefd, fp->txtaddr, fp->txtaddr+fp->txtsz, fp->txtaddr, "text"); 119 if(kflag || fp->dataddr >= mach->utop) { 120 setmap(map, corefd, fp->dataddr, ~0, fp->dataddr, "data"); 121 return map; 122 } 123 n = stacktop(pid); 124 if (n == 0) { 125 setmap(map, corefd, fp->dataddr, mach->utop, fp->dataddr, "data"); 126 return map; 127 } 128 setmap(map, corefd, fp->dataddr, n, fp->dataddr, "data"); 129 return map; 130 } 131 132 int 133 findseg(Map *map, char *name) 134 { 135 int i; 136 137 if (!map) 138 return -1; 139 for (i = 0; i < map->nsegs; i++) 140 if (map->seg[i].inuse && !strcmp(map->seg[i].name, name)) 141 return i; 142 return -1; 143 } 144 145 void 146 unusemap(Map *map, int i) 147 { 148 if (map != 0 && 0 <= i && i < map->nsegs) 149 map->seg[i].inuse = 0; 150 } 151 152 Map* 153 loadmap(Map *map, int fd, Fhdr *fp) 154 { 155 map = newmap(map, 2); 156 if (map == 0) 157 return 0; 158 159 map->seg[0].b = fp->txtaddr; 160 map->seg[0].e = fp->txtaddr+fp->txtsz; 161 map->seg[0].f = fp->txtoff; 162 map->seg[0].fd = fd; 163 map->seg[0].inuse = 1; 164 map->seg[0].name = "text"; 165 map->seg[1].b = fp->dataddr; 166 map->seg[1].e = fp->dataddr+fp->datsz; 167 map->seg[1].f = fp->datoff; 168 map->seg[1].fd = fd; 169 map->seg[1].inuse = 1; 170 map->seg[1].name = "data"; 171 return map; 172 } 173