plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

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 }