|  | #include <u.h> | 
|  | #include <libc.h> | 
|  | #include <bio.h> | 
|  | #include <ctype.h> | 
|  | #include <mach.h> | 
|  | #define Extern extern | 
|  | #include "acid.h" | 
|  | #include "y.tab.h" | 
|  |  | 
|  | static int syren; | 
|  |  | 
|  | Lsym* | 
|  | unique(char *buf, Symbol *s) | 
|  | { | 
|  | Lsym *l; | 
|  | int i, renamed; | 
|  |  | 
|  | renamed = 0; | 
|  | strcpy(buf, s->xname); | 
|  | for(;;) { | 
|  | l = look(buf); | 
|  | if(l == 0 || (l->lexval == Tid && l->v->set == 0)) | 
|  | break; | 
|  |  | 
|  | if(syren == 0 && !quiet) { | 
|  | print("Symbol renames:\n"); | 
|  | syren = 1; | 
|  | } | 
|  | i = strlen(buf)+1; | 
|  | memmove(buf+1, buf, i); | 
|  | buf[0] = '$'; | 
|  | renamed++; | 
|  | if(renamed > 5 && !quiet) { | 
|  | print("Too many renames; must be X source!\n"); | 
|  | break; | 
|  | } | 
|  | } | 
|  | if(renamed && !quiet) | 
|  | print("\t%s=%s %c/%L\n", s->xname, buf, s->type, s->loc); | 
|  | if(l == 0) | 
|  | l = enter(buf, Tid); | 
|  | s->aux = l; | 
|  | return l; | 
|  | } | 
|  |  | 
|  | void | 
|  | varsym(void) | 
|  | { | 
|  | Lsym *l; | 
|  | Fhdr *fp; | 
|  |  | 
|  | l = mkvar("symbols"); | 
|  | if(l->v->set) | 
|  | return; | 
|  |  | 
|  | l->v->set = 1; | 
|  | l->v->type = TLIST; | 
|  | l->v->store.u.l = nil; | 
|  |  | 
|  | for(fp=fhdrlist; fp; fp=fp->next){ | 
|  | if(fp->ftype == FCORE) | 
|  | continue; | 
|  | addvarsym(fp); | 
|  | } | 
|  | if(l->v->store.u.l == nil) | 
|  | print("no debugging symbols\n"); | 
|  | } | 
|  |  | 
|  | void | 
|  | addvarsym(Fhdr *fp) | 
|  | { | 
|  | int i; | 
|  | Symbol s; | 
|  | Lsym *l; | 
|  | String *file; | 
|  | u64int v; | 
|  | char buf[65536];	/* Some of those C++ names are really big */ | 
|  | List *list, **tail, *tl; | 
|  |  | 
|  | if(fp == nil) | 
|  | return; | 
|  |  | 
|  | l = look("symbols"); | 
|  | if(l == nil) | 
|  | return; | 
|  |  | 
|  | l->v->set = 1; | 
|  | l->v->type = TLIST; | 
|  | tail = &l->v->store.u.l; | 
|  | while(*tail) | 
|  | tail = &(*tail)->next; | 
|  |  | 
|  | file = strnode(fp->filename); | 
|  | for(i=0; findexsym(fp, i, &s)>=0; i++){ | 
|  | switch(s.type) { | 
|  | case 'T': | 
|  | case 'L': | 
|  | case 'D': | 
|  | case 'B': | 
|  | case 'b': | 
|  | case 'd': | 
|  | case 'l': | 
|  | case 't': | 
|  | if(s.name[0] == '.') | 
|  | continue; | 
|  | if(s.loc.type != LADDR) | 
|  | continue; | 
|  | v = s.loc.addr; | 
|  | tl = al(TLIST); | 
|  | *tail = tl; | 
|  | tail = &tl->next; | 
|  |  | 
|  | l = unique(buf, &s); | 
|  | l->v->set = 1; | 
|  | l->v->type = TINT; | 
|  | l->v->store.u.ival = v; | 
|  | if(l->v->store.comt == 0) | 
|  | l->v->store.fmt = 'X'; | 
|  |  | 
|  | /* Enter as list of { name, type, value, file, xname } */ | 
|  | list = al(TSTRING); | 
|  | tl->store.u.l = list; | 
|  | list->store.u.string = strnode(buf); | 
|  | list->store.fmt = 's'; | 
|  |  | 
|  | list->next = al(TINT); | 
|  | list = list->next; | 
|  | list->store.fmt = 'c'; | 
|  | list->store.u.ival = s.type; | 
|  |  | 
|  | list->next = al(TINT); | 
|  | list = list->next; | 
|  | list->store.fmt = 'X'; | 
|  | list->store.u.ival = v; | 
|  |  | 
|  | list->next = al(TSTRING); | 
|  | list = list->next; | 
|  | list->store.fmt = 's'; | 
|  | list->store.u.string = file; | 
|  |  | 
|  | list->next = al(TSTRING); | 
|  | list = list->next; | 
|  | list->store.fmt = 's'; | 
|  | list->store.u.string = strnode(s.name); | 
|  | } | 
|  | } | 
|  | *tail = nil; | 
|  | } | 
|  |  | 
|  | static int | 
|  | infile(List *list, char *file, char **name) | 
|  | { | 
|  | /* name */ | 
|  | if(list->type != TSTRING) | 
|  | return 0; | 
|  | *name = list->store.u.string->string; | 
|  | if(list->next == nil) | 
|  | return 0; | 
|  | list = list->next; | 
|  |  | 
|  | /* type character */ | 
|  | if(list->next == nil) | 
|  | return 0; | 
|  | list = list->next; | 
|  |  | 
|  | /* address */ | 
|  | if(list->next == nil) | 
|  | return 0; | 
|  | list = list->next; | 
|  |  | 
|  | /* file */ | 
|  | if(list->type != TSTRING) | 
|  | return 0; | 
|  | return strcmp(list->store.u.string->string, file) == 0; | 
|  | } | 
|  |  | 
|  | void | 
|  | delvarsym(char *file) | 
|  | { | 
|  | char *name; | 
|  | Lsym *l; | 
|  | List **lp, *p; | 
|  |  | 
|  | l = look("symbols"); | 
|  | if(l == nil) | 
|  | return; | 
|  |  | 
|  | if(l->v->type != TLIST) | 
|  | return; | 
|  |  | 
|  | for(lp=&l->v->store.u.l; *lp; lp=&(*lp)->next){ | 
|  | while(*lp){ | 
|  | p = *lp; | 
|  | if(p->type != TLIST) | 
|  | break; | 
|  | if(!infile(p->store.u.l, file, &name)) | 
|  | break; | 
|  | *lp = p->next; | 
|  | /* XXX remove from hash tables */ | 
|  | } | 
|  | if(*lp == nil) | 
|  | break; | 
|  | } | 
|  | } | 
|  |  | 
|  | void | 
|  | varreg(void) | 
|  | { | 
|  | Lsym *l; | 
|  | Value *v; | 
|  | Regdesc *r; | 
|  | List **tail, *li; | 
|  |  | 
|  | l = mkvar("registers"); | 
|  | v = l->v; | 
|  | v->set = 1; | 
|  | v->type = TLIST; | 
|  | v->store.u.l = 0; | 
|  | tail = &v->store.u.l; | 
|  |  | 
|  | if(mach == nil) | 
|  | return; | 
|  |  | 
|  | for(r = mach->reglist; r->name; r++) { | 
|  | l = mkvar(r->name); | 
|  | v = l->v; | 
|  | v->set = 1; | 
|  | v->store.u.reg.name = r->name; | 
|  | v->store.u.reg.thread = 0; | 
|  | v->store.fmt = r->format; | 
|  | v->type = TREG; | 
|  |  | 
|  | li = al(TSTRING); | 
|  | li->store.u.string = strnode(r->name); | 
|  | li->store.fmt = 's'; | 
|  | *tail = li; | 
|  | tail = &li->next; | 
|  | } | 
|  |  | 
|  | l = mkvar("bpinst");	/* Breakpoint text */ | 
|  | v = l->v; | 
|  | v->type = TSTRING; | 
|  | v->store.fmt = 's'; | 
|  | v->set = 1; | 
|  | v->store.u.string = gmalloc(sizeof(String)); | 
|  | v->store.u.string->len = mach->bpsize; | 
|  | v->store.u.string->string = gmalloc(mach->bpsize); | 
|  | memmove(v->store.u.string->string, mach->bpinst, mach->bpsize); | 
|  | } | 
|  |  | 
|  | void | 
|  | loadvars(void) | 
|  | { | 
|  | Lsym *l; | 
|  | Value *v; | 
|  |  | 
|  | l =  mkvar("proc"); | 
|  | v = l->v; | 
|  | v->type = TINT; | 
|  | v->store.fmt = 'X'; | 
|  | v->set = 1; | 
|  | v->store.u.ival = 0; | 
|  |  | 
|  | l = mkvar("pid");		/* Current process */ | 
|  | v = l->v; | 
|  | v->type = TINT; | 
|  | v->store.fmt = 'D'; | 
|  | v->set = 1; | 
|  | v->store.u.ival = 0; | 
|  |  | 
|  | mkvar("notes");			/* Pending notes */ | 
|  |  | 
|  | l = mkvar("proclist");		/* Attached processes */ | 
|  | l->v->type = TLIST; | 
|  | } | 
|  |  | 
|  | String* | 
|  | strnodlen(char *name, int len) | 
|  | { | 
|  | String *s; | 
|  |  | 
|  | s = gmalloc(sizeof(String)+len+1); | 
|  | s->string = (char*)s+sizeof(String); | 
|  | s->len = len; | 
|  | if(name != 0) | 
|  | memmove(s->string, name, len); | 
|  | s->string[len] = '\0'; | 
|  |  | 
|  | s->gc.gclink = gcl; | 
|  | gcl = (Gc*)s; | 
|  |  | 
|  | return s; | 
|  | } | 
|  |  | 
|  | String* | 
|  | strnode(char *name) | 
|  | { | 
|  | return strnodlen(name, strlen(name)); | 
|  | } | 
|  |  | 
|  | String* | 
|  | runenode(Rune *name) | 
|  | { | 
|  | int len; | 
|  | Rune *p; | 
|  | String *s; | 
|  |  | 
|  | p = name; | 
|  | for(len = 0; *p; p++) | 
|  | len++; | 
|  |  | 
|  | len++; | 
|  | len *= sizeof(Rune); | 
|  | s = gmalloc(sizeof(String)+len); | 
|  | s->string = (char*)s+sizeof(String); | 
|  | s->len = len; | 
|  | memmove(s->string, name, len); | 
|  |  | 
|  | s->gc.gclink = gcl; | 
|  | gcl = (Gc*)s; | 
|  |  | 
|  | return s; | 
|  | } | 
|  |  | 
|  | String* | 
|  | stradd(String *l, String *r) | 
|  | { | 
|  | int len; | 
|  | String *s; | 
|  |  | 
|  | len = l->len+r->len; | 
|  | s = gmalloc(sizeof(String)+len+1); | 
|  | s->gc.gclink = gcl; | 
|  | gcl = (Gc*)s; | 
|  | s->len = len; | 
|  | s->string = (char*)s+sizeof(String); | 
|  | memmove(s->string, l->string, l->len); | 
|  | memmove(s->string+l->len, r->string, r->len); | 
|  | s->string[s->len] = 0; | 
|  | return s; | 
|  | } | 
|  |  | 
|  | int | 
|  | scmp(String *sr, String *sl) | 
|  | { | 
|  | if(sr->len != sl->len) | 
|  | return 0; | 
|  |  | 
|  | if(memcmp(sr->string, sl->string, sl->len)) | 
|  | return 0; | 
|  |  | 
|  | return 1; | 
|  | } |