#include #include #include #include /* * XXX could remove the rock by hiding it in a special regs. * That would still be sleazy but would be thread-safe. */ static struct { int found; int nframe; Loc l; char *fn; char *var; char *reg; } rock; static int ltrace(Map *map, Regs *regs, u64int pc, u64int nextpc, Symbol *sym, int depth) { u64int v; Symbol s1; USED(pc); USED(nextpc); USED(depth); if(sym==nil || strcmp(sym->name, rock.fn) != 0) return ++rock.nframe < 40; if(rock.reg){ if(rget(regs, rock.reg, &v) < 0) return 0; rock.l = locconst(v); rock.found = 1; return 0; } if(lookuplsym(sym, rock.var, &s1) < 0) return 0; if(locsimplify(map, regs, s1.loc, &rock.l) < 0) return 0; if(rock.l.type == LREG && rget(regs, rock.l.reg, &v) >= 0) rock.l = locconst(v); if(rock.l.type != LADDR && rock.l.type != LCONST) return 0; rock.found = 1; return 0; } int localaddr(Map *map, Regs *regs, char *fn, char *var, u64int *val) { Regdesc *rp; rock.found = 0; rock.nframe = 0; rock.fn = fn; rock.reg = nil; rock.var = nil; for(rp=mach->reglist; rp->name; rp++) if(strcmp(rp->name, var) == 0) rock.reg = rp->name; if(!rock.reg) rock.var = var; stacktrace(map, regs, ltrace); if(rock.found){ *val = rock.l.addr; return 0; } return -1; }