#include #include #include #include #include #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->name); 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->name, buf, s->type, s->loc); if(l == 0) l = enter(buf, Tid); 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; ulong 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 } */ 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; } } *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; }