rsc | 564ca70 | 2004-04-19 19:32:07 +0000 | [diff] [blame] | 1 | #include <u.h> |
| 2 | #include <libc.h> |
| 3 | #include <bio.h> |
| 4 | #include <ctype.h> |
| 5 | #include <mach.h> |
| 6 | #define Extern extern |
| 7 | #include "acid.h" |
| 8 | #include "y.tab.h" |
| 9 | |
| 10 | static int syren; |
| 11 | |
| 12 | Lsym* |
| 13 | unique(char *buf, Symbol *s) |
| 14 | { |
| 15 | Lsym *l; |
| 16 | int i, renamed; |
| 17 | |
| 18 | renamed = 0; |
rsc | 62faed5 | 2005-11-29 05:12:48 +0000 | [diff] [blame] | 19 | strcpy(buf, s->xname); |
rsc | 564ca70 | 2004-04-19 19:32:07 +0000 | [diff] [blame] | 20 | for(;;) { |
| 21 | l = look(buf); |
| 22 | if(l == 0 || (l->lexval == Tid && l->v->set == 0)) |
| 23 | break; |
| 24 | |
| 25 | if(syren == 0 && !quiet) { |
| 26 | print("Symbol renames:\n"); |
| 27 | syren = 1; |
| 28 | } |
| 29 | i = strlen(buf)+1; |
| 30 | memmove(buf+1, buf, i); |
| 31 | buf[0] = '$'; |
| 32 | renamed++; |
| 33 | if(renamed > 5 && !quiet) { |
| 34 | print("Too many renames; must be X source!\n"); |
| 35 | break; |
| 36 | } |
| 37 | } |
| 38 | if(renamed && !quiet) |
rsc | 62faed5 | 2005-11-29 05:12:48 +0000 | [diff] [blame] | 39 | print("\t%s=%s %c/%L\n", s->xname, buf, s->type, s->loc); |
rsc | 564ca70 | 2004-04-19 19:32:07 +0000 | [diff] [blame] | 40 | if(l == 0) |
| 41 | l = enter(buf, Tid); |
rsc | 62faed5 | 2005-11-29 05:12:48 +0000 | [diff] [blame] | 42 | s->aux = l; |
rsc | 564ca70 | 2004-04-19 19:32:07 +0000 | [diff] [blame] | 43 | return l; |
| 44 | } |
| 45 | |
| 46 | void |
| 47 | varsym(void) |
| 48 | { |
| 49 | Lsym *l; |
| 50 | Fhdr *fp; |
| 51 | |
| 52 | l = mkvar("symbols"); |
| 53 | if(l->v->set) |
| 54 | return; |
| 55 | |
| 56 | l->v->set = 1; |
| 57 | l->v->type = TLIST; |
| 58 | l->v->store.u.l = nil; |
| 59 | |
| 60 | for(fp=fhdrlist; fp; fp=fp->next){ |
| 61 | if(fp->ftype == FCORE) |
| 62 | continue; |
| 63 | addvarsym(fp); |
| 64 | } |
rsc | 564ca70 | 2004-04-19 19:32:07 +0000 | [diff] [blame] | 65 | if(l->v->store.u.l == nil) |
| 66 | print("no debugging symbols\n"); |
| 67 | } |
| 68 | |
| 69 | void |
| 70 | addvarsym(Fhdr *fp) |
| 71 | { |
| 72 | int i; |
| 73 | Symbol s; |
| 74 | Lsym *l; |
| 75 | String *file; |
| 76 | ulong v; |
rsc | 689be54 | 2005-11-28 00:39:42 +0000 | [diff] [blame] | 77 | char buf[65536]; /* Some of those C++ names are really big */ |
rsc | 564ca70 | 2004-04-19 19:32:07 +0000 | [diff] [blame] | 78 | List *list, **tail, *tl; |
| 79 | |
| 80 | if(fp == nil) |
| 81 | return; |
| 82 | |
| 83 | l = look("symbols"); |
| 84 | if(l == nil) |
| 85 | return; |
| 86 | |
| 87 | l->v->set = 1; |
| 88 | l->v->type = TLIST; |
| 89 | tail = &l->v->store.u.l; |
| 90 | while(*tail) |
| 91 | tail = &(*tail)->next; |
| 92 | |
| 93 | file = strnode(fp->filename); |
| 94 | for(i=0; findexsym(fp, i, &s)>=0; i++){ |
| 95 | switch(s.type) { |
| 96 | case 'T': |
| 97 | case 'L': |
| 98 | case 'D': |
| 99 | case 'B': |
| 100 | case 'b': |
| 101 | case 'd': |
| 102 | case 'l': |
| 103 | case 't': |
| 104 | if(s.name[0] == '.') |
| 105 | continue; |
| 106 | if(s.loc.type != LADDR) |
| 107 | continue; |
| 108 | v = s.loc.addr; |
| 109 | tl = al(TLIST); |
| 110 | *tail = tl; |
| 111 | tail = &tl->next; |
| 112 | |
| 113 | l = unique(buf, &s); |
| 114 | l->v->set = 1; |
| 115 | l->v->type = TINT; |
| 116 | l->v->store.u.ival = v; |
| 117 | if(l->v->store.comt == 0) |
| 118 | l->v->store.fmt = 'X'; |
| 119 | |
rsc | 62faed5 | 2005-11-29 05:12:48 +0000 | [diff] [blame] | 120 | /* Enter as list of { name, type, value, file, xname } */ |
rsc | 564ca70 | 2004-04-19 19:32:07 +0000 | [diff] [blame] | 121 | list = al(TSTRING); |
| 122 | tl->store.u.l = list; |
| 123 | list->store.u.string = strnode(buf); |
| 124 | list->store.fmt = 's'; |
rsc | 62faed5 | 2005-11-29 05:12:48 +0000 | [diff] [blame] | 125 | |
rsc | 564ca70 | 2004-04-19 19:32:07 +0000 | [diff] [blame] | 126 | list->next = al(TINT); |
| 127 | list = list->next; |
| 128 | list->store.fmt = 'c'; |
| 129 | list->store.u.ival = s.type; |
rsc | 62faed5 | 2005-11-29 05:12:48 +0000 | [diff] [blame] | 130 | |
rsc | 564ca70 | 2004-04-19 19:32:07 +0000 | [diff] [blame] | 131 | list->next = al(TINT); |
| 132 | list = list->next; |
| 133 | list->store.fmt = 'X'; |
| 134 | list->store.u.ival = v; |
rsc | 62faed5 | 2005-11-29 05:12:48 +0000 | [diff] [blame] | 135 | |
rsc | 564ca70 | 2004-04-19 19:32:07 +0000 | [diff] [blame] | 136 | list->next = al(TSTRING); |
| 137 | list = list->next; |
| 138 | list->store.fmt = 's'; |
| 139 | list->store.u.string = file; |
rsc | 62faed5 | 2005-11-29 05:12:48 +0000 | [diff] [blame] | 140 | |
| 141 | list->next = al(TSTRING); |
| 142 | list = list->next; |
| 143 | list->store.fmt = 's'; |
rsc | 0932b48 | 2006-02-14 19:41:28 +0000 | [diff] [blame] | 144 | list->store.u.string = strnode(s.name); |
rsc | 564ca70 | 2004-04-19 19:32:07 +0000 | [diff] [blame] | 145 | } |
| 146 | } |
| 147 | *tail = nil; |
| 148 | } |
| 149 | |
| 150 | static int |
| 151 | infile(List *list, char *file, char **name) |
| 152 | { |
| 153 | /* name */ |
| 154 | if(list->type != TSTRING) |
| 155 | return 0; |
| 156 | *name = list->store.u.string->string; |
| 157 | if(list->next == nil) |
| 158 | return 0; |
| 159 | list = list->next; |
| 160 | |
| 161 | /* type character */ |
| 162 | if(list->next == nil) |
| 163 | return 0; |
| 164 | list = list->next; |
| 165 | |
| 166 | /* address */ |
| 167 | if(list->next == nil) |
| 168 | return 0; |
| 169 | list = list->next; |
| 170 | |
| 171 | /* file */ |
| 172 | if(list->type != TSTRING) |
| 173 | return 0; |
| 174 | return strcmp(list->store.u.string->string, file) == 0; |
| 175 | } |
| 176 | |
| 177 | void |
| 178 | delvarsym(char *file) |
| 179 | { |
| 180 | char *name; |
| 181 | Lsym *l; |
| 182 | List **lp, *p; |
| 183 | |
| 184 | l = look("symbols"); |
| 185 | if(l == nil) |
| 186 | return; |
| 187 | |
| 188 | if(l->v->type != TLIST) |
| 189 | return; |
| 190 | |
| 191 | for(lp=&l->v->store.u.l; *lp; lp=&(*lp)->next){ |
| 192 | while(*lp){ |
| 193 | p = *lp; |
| 194 | if(p->type != TLIST) |
| 195 | break; |
| 196 | if(!infile(p->store.u.l, file, &name)) |
| 197 | break; |
| 198 | *lp = p->next; |
| 199 | /* XXX remove from hash tables */ |
| 200 | } |
| 201 | if(*lp == nil) |
| 202 | break; |
| 203 | } |
| 204 | } |
| 205 | |
| 206 | void |
| 207 | varreg(void) |
| 208 | { |
| 209 | Lsym *l; |
| 210 | Value *v; |
| 211 | Regdesc *r; |
| 212 | List **tail, *li; |
| 213 | |
| 214 | l = mkvar("registers"); |
| 215 | v = l->v; |
| 216 | v->set = 1; |
| 217 | v->type = TLIST; |
| 218 | v->store.u.l = 0; |
| 219 | tail = &v->store.u.l; |
| 220 | |
| 221 | if(mach == nil) |
| 222 | return; |
| 223 | |
| 224 | for(r = mach->reglist; r->name; r++) { |
| 225 | l = mkvar(r->name); |
| 226 | v = l->v; |
| 227 | v->set = 1; |
rsc | 281c90a | 2005-02-11 00:01:49 +0000 | [diff] [blame] | 228 | v->store.u.reg.name = r->name; |
| 229 | v->store.u.reg.thread = 0; |
rsc | 564ca70 | 2004-04-19 19:32:07 +0000 | [diff] [blame] | 230 | v->store.fmt = r->format; |
rsc | 4f2ac1b | 2005-01-23 22:48:19 +0000 | [diff] [blame] | 231 | v->type = TREG; |
rsc | 564ca70 | 2004-04-19 19:32:07 +0000 | [diff] [blame] | 232 | |
| 233 | li = al(TSTRING); |
| 234 | li->store.u.string = strnode(r->name); |
| 235 | li->store.fmt = 's'; |
| 236 | *tail = li; |
| 237 | tail = &li->next; |
| 238 | } |
| 239 | |
| 240 | l = mkvar("bpinst"); /* Breakpoint text */ |
| 241 | v = l->v; |
| 242 | v->type = TSTRING; |
| 243 | v->store.fmt = 's'; |
| 244 | v->set = 1; |
| 245 | v->store.u.string = gmalloc(sizeof(String)); |
| 246 | v->store.u.string->len = mach->bpsize; |
| 247 | v->store.u.string->string = gmalloc(mach->bpsize); |
| 248 | memmove(v->store.u.string->string, mach->bpinst, mach->bpsize); |
| 249 | } |
| 250 | |
| 251 | void |
| 252 | loadvars(void) |
| 253 | { |
| 254 | Lsym *l; |
| 255 | Value *v; |
| 256 | |
| 257 | l = mkvar("proc"); |
| 258 | v = l->v; |
| 259 | v->type = TINT; |
| 260 | v->store.fmt = 'X'; |
| 261 | v->set = 1; |
| 262 | v->store.u.ival = 0; |
| 263 | |
| 264 | l = mkvar("pid"); /* Current process */ |
| 265 | v = l->v; |
| 266 | v->type = TINT; |
| 267 | v->store.fmt = 'D'; |
| 268 | v->set = 1; |
| 269 | v->store.u.ival = 0; |
| 270 | |
| 271 | mkvar("notes"); /* Pending notes */ |
| 272 | |
| 273 | l = mkvar("proclist"); /* Attached processes */ |
| 274 | l->v->type = TLIST; |
| 275 | } |
| 276 | |
| 277 | String* |
| 278 | strnodlen(char *name, int len) |
| 279 | { |
| 280 | String *s; |
| 281 | |
| 282 | s = gmalloc(sizeof(String)+len+1); |
| 283 | s->string = (char*)s+sizeof(String); |
| 284 | s->len = len; |
| 285 | if(name != 0) |
| 286 | memmove(s->string, name, len); |
| 287 | s->string[len] = '\0'; |
| 288 | |
| 289 | s->gc.gclink = gcl; |
| 290 | gcl = (Gc*)s; |
| 291 | |
| 292 | return s; |
| 293 | } |
| 294 | |
| 295 | String* |
| 296 | strnode(char *name) |
| 297 | { |
| 298 | return strnodlen(name, strlen(name)); |
| 299 | } |
| 300 | |
| 301 | String* |
| 302 | runenode(Rune *name) |
| 303 | { |
| 304 | int len; |
| 305 | Rune *p; |
| 306 | String *s; |
| 307 | |
| 308 | p = name; |
| 309 | for(len = 0; *p; p++) |
| 310 | len++; |
| 311 | |
| 312 | len++; |
| 313 | len *= sizeof(Rune); |
| 314 | s = gmalloc(sizeof(String)+len); |
| 315 | s->string = (char*)s+sizeof(String); |
| 316 | s->len = len; |
| 317 | memmove(s->string, name, len); |
| 318 | |
| 319 | s->gc.gclink = gcl; |
| 320 | gcl = (Gc*)s; |
| 321 | |
| 322 | return s; |
| 323 | } |
| 324 | |
| 325 | String* |
| 326 | stradd(String *l, String *r) |
| 327 | { |
| 328 | int len; |
| 329 | String *s; |
| 330 | |
| 331 | len = l->len+r->len; |
| 332 | s = gmalloc(sizeof(String)+len+1); |
| 333 | s->gc.gclink = gcl; |
| 334 | gcl = (Gc*)s; |
| 335 | s->len = len; |
| 336 | s->string = (char*)s+sizeof(String); |
| 337 | memmove(s->string, l->string, l->len); |
| 338 | memmove(s->string+l->len, r->string, r->len); |
| 339 | s->string[s->len] = 0; |
| 340 | return s; |
| 341 | } |
| 342 | |
| 343 | int |
| 344 | scmp(String *sr, String *sl) |
| 345 | { |
| 346 | if(sr->len != sl->len) |
| 347 | return 0; |
| 348 | |
| 349 | if(memcmp(sr->string, sl->string, sl->len)) |
| 350 | return 0; |
| 351 | |
| 352 | return 1; |
| 353 | } |