localaddr.c (1333B)
1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include <mach.h> 5 6 /* 7 * XXX could remove the rock by hiding it in a special regs. 8 * That would still be sleazy but would be thread-safe. 9 */ 10 11 static struct { 12 int found; 13 int nframe; 14 Loc l; 15 char *fn; 16 char *var; 17 char *reg; 18 } rock; 19 20 static int 21 ltrace(Map *map, Regs *regs, u64int pc, u64int nextpc, Symbol *sym, int depth) 22 { 23 u64int v; 24 Symbol s1; 25 26 USED(pc); 27 USED(nextpc); 28 USED(depth); 29 30 if(sym==nil || strcmp(sym->name, rock.fn) != 0) 31 return ++rock.nframe < 40; 32 if(rock.reg){ 33 if(rget(regs, rock.reg, &v) < 0) 34 return 0; 35 rock.l = locconst(v); 36 rock.found = 1; 37 return 0; 38 } 39 if(lookuplsym(sym, rock.var, &s1) < 0) 40 return 0; 41 if(locsimplify(map, regs, s1.loc, &rock.l) < 0) 42 return 0; 43 if(rock.l.type == LREG && rget(regs, rock.l.reg, &v) >= 0) 44 rock.l = locconst(v); 45 if(rock.l.type != LADDR && rock.l.type != LCONST) 46 return 0; 47 rock.found = 1; 48 return 0; 49 } 50 51 int 52 localaddr(Map *map, Regs *regs, char *fn, char *var, u64int *val) 53 { 54 Regdesc *rp; 55 56 rock.found = 0; 57 rock.nframe = 0; 58 rock.fn = fn; 59 rock.reg = nil; 60 rock.var = nil; 61 for(rp=mach->reglist; rp->name; rp++) 62 if(strcmp(rp->name, var) == 0) 63 rock.reg = rp->name; 64 if(!rock.reg) 65 rock.var = var; 66 stacktrace(map, regs, ltrace); 67 if(rock.found){ 68 *val = rock.l.addr; 69 return 0; 70 } 71 return -1; 72 }