From a84cbb2a17c9d0b88c561d5b7cb50d79a19e7c46 Mon Sep 17 00:00:00 2001 From: rsc Date: Mon, 19 Apr 2004 19:29:25 +0000 Subject: libmach --- src/libmach/localaddr.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/libmach/localaddr.c (limited to 'src/libmach/localaddr.c') diff --git a/src/libmach/localaddr.c b/src/libmach/localaddr.c new file mode 100644 index 00000000..1b1dea73 --- /dev/null +++ b/src/libmach/localaddr.c @@ -0,0 +1,56 @@ +#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; +} rock; + +static int +ltrace(Map *map, Regs *regs, ulong pc, ulong nextpc, Symbol *sym, int depth) +{ + ulong v; + Symbol s1; + + USED(pc); + USED(nextpc); + USED(depth); + + if(sym==nil || strcmp(sym->name, rock.fn) != 0) + return ++rock.nframe < 40; + 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, ulong *val) +{ + rock.found = 0; + rock.nframe = 0; + rock.fn = fn; + rock.var = var; + stacktrace(map, regs, ltrace); + if(rock.found){ + *val = rock.l.addr; + return 0; + } + return -1; +} -- cgit v1.2.3