summaryrefslogtreecommitdiff
path: root/utils/libmach/sym.c
diff options
context:
space:
mode:
authorforsyth <forsyth@vitanuova.com>2010-04-27 12:51:13 +0100
committerforsyth <forsyth@vitanuova.com>2010-04-27 12:51:13 +0100
commitd67b7dad77bb8aa973dad1f7c3ab0c309b114278 (patch)
tree6794120fb327d6de19cf05eed53f80d877781a3e /utils/libmach/sym.c
parent09da2e137d5eb0c940df35d989e4c31ec0654fc4 (diff)
20100427-1251
Diffstat (limited to 'utils/libmach/sym.c')
-rw-r--r--utils/libmach/sym.c394
1 files changed, 182 insertions, 212 deletions
diff --git a/utils/libmach/sym.c b/utils/libmach/sym.c
index 476e5e3d..751d933d 100644
--- a/utils/libmach/sym.c
+++ b/utils/libmach/sym.c
@@ -8,7 +8,6 @@
typedef struct txtsym Txtsym;
typedef struct file File;
typedef struct hist Hist;
-typedef struct pcl Pcl;
struct txtsym { /* Text Symbol table */
int n; /* number of local vars */
@@ -16,27 +15,20 @@ struct txtsym { /* Text Symbol table */
Sym *sym; /* function symbol entry */
};
-struct hist { /* Stack of include files & #line directives */
+struct hist { /* Stack of include files & #line directives */
char *name; /* Assumes names Null terminated in file */
long line; /* line # where it was included */
long offset; /* line # of #line directive */
};
-struct pcl {
- uchar *pcline; /* start of pcline data for this file */
- long pc; /* starting pc for pcline crunch */
- long line; /* starting line for pcline crunch */
-};
-
struct file { /* Per input file header to history stack */
- long addr; /* address of first text sym */
- union {
- Txtsym *ftxt; /* first text symbol */
- Sym *fsym; /* only during initilization */
- } u0;
- int n; /* size of history stack */
- Hist *hist; /* history stack */
- Pcl pcl; /* pcline startup data */
+ uvlong addr; /* address of first text sym */
+ /* union { */
+ Txtsym *txt; /* first text symbol */
+ Sym *sym; /* only during initilization */
+ /* }; */
+ int n; /* size of history stack */
+ Hist *hist; /* history stack */
};
static int debug = 0;
@@ -53,19 +45,18 @@ static long nfiles; /* number of files */
static long nglob; /* number of globals */
static long nhist; /* number of history stack entries */
static long nsym; /* number of symbols */
-static long ntxt; /* number of text symbols */
+static int ntxt; /* number of text symbols */
static uchar *pcline; /* start of pc-line state table */
static uchar *pclineend; /* end of pc-line table */
-static int npcl; /* number of files pcl-decoded so far */
static uchar *spoff; /* start of pc-sp state table */
static uchar *spoffend; /* end of pc-sp offset table */
static Sym *symbols; /* symbol table */
static Txtsym *txt; /* Base of text symbol table */
-static long txtstart; /* start of text segment */
-static long txtend; /* end of text segment */
+static uvlong txtstart; /* start of text segment */
+static uvlong txtend; /* end of text segment */
static void cleansyms(void);
-static int decodename(Biobuf*, Sym*);
+static long decodename(Biobuf*, Sym*);
static short *encfname(char*);
static int fline(char*, int, long, Hist*, Hist**);
static void fillsym(Sym*, Symbol*);
@@ -73,11 +64,8 @@ static int findglobal(char*, Symbol*);
static int findlocvar(Symbol*, char *, Symbol*);
static int findtext(char*, Symbol*);
static int hcomp(Hist*, short*);
-static int hline(File*, short*, ulong*);
+static int hline(File*, short*, long*);
static void printhist(char*, Hist*, int);
-static long pcl2line(ulong, Pcl *, Pcl *);
-static long pc2fline(ulong, File **);
-static int pc2filex(ulong);
static int buildtbls(void);
static int symcomp(void*, void*);
static int symerrmsg(int, char*);
@@ -91,9 +79,10 @@ int
syminit(int fd, Fhdr *fp)
{
Sym *p;
- int i, size;
+ long i, l, size;
+ vlong vl;
Biobuf b;
- extern void thumbpctab(Biobuf*, Fhdr*);
+ int svalsz;
if(fp->symsz == 0)
return 0;
@@ -108,22 +97,30 @@ syminit(int fd, Fhdr *fp)
werrstr("can't malloc %ld bytes", fp->symsz);
return -1;
}
-
Binit(&b, fd, OREAD);
Bseek(&b, fp->symoff, 0);
nsym = 0;
size = 0;
for(p = symbols; size < fp->symsz; p++, nsym++) {
- if(Bread(&b, &p->value, sizeof(p->value)) != sizeof(p->value))
- return symerrmsg(sizeof(p->value), "symbol");
- p->value = beswal(p->value);
+ if(fp->_magic && (fp->magic & HDR_MAGIC)){
+ svalsz = 8;
+ if(Bread(&b, &vl, 8) != 8)
+ return symerrmsg(8, "symbol");
+ p->value = beswav(vl);
+ }
+ else{
+ svalsz = 4;
+ if(Bread(&b, &l, 4) != 4)
+ return symerrmsg(4, "symbol");
+ p->value = (u32int)beswal(l);
+ }
if(Bread(&b, &p->type, sizeof(p->type)) != sizeof(p->type))
return symerrmsg(sizeof(p->value), "symbol");
i = decodename(&b, p);
if(i < 0)
return -1;
- size += i+sizeof(p->value)+sizeof(p->type);
+ size += i+svalsz+sizeof(p->type);
/* count global & auto vars, text symbols, and file names */
switch (p->type) {
@@ -164,7 +161,7 @@ syminit(int fd, Fhdr *fp)
}
}
if (debug)
- fprint(2,"NG: %ld NT: %ld NF: %d\n", nglob, ntxt, fpmax);
+ print("NG: %ld NT: %d NF: %d\n", nglob, ntxt, fpmax);
if (fp->sppcsz) { /* pc-sp offset table */
spoff = (uchar *)malloc(fp->sppcsz);
if(spoff == 0) {
@@ -172,8 +169,7 @@ syminit(int fd, Fhdr *fp)
return -1;
}
Bseek(&b, fp->sppcoff, 0);
- i = Bread(&b, spoff, fp->sppcsz);
- if(i != fp->sppcsz){
+ if(Bread(&b, spoff, fp->sppcsz) != fp->sppcsz){
spoff = 0;
return symerrmsg(fp->sppcsz, "sp-pc");
}
@@ -186,8 +182,7 @@ syminit(int fd, Fhdr *fp)
return -1;
}
Bseek(&b, fp->lnpcoff, 0);
- i = Bread(&b, pcline, fp->lnpcsz);
- if(i != fp->lnpcsz){
+ if(Bread(&b, pcline, fp->lnpcsz) != fp->lnpcsz){
pcline = 0;
return symerrmsg(fp->lnpcsz, "pc-line");
}
@@ -205,12 +200,13 @@ symerrmsg(int n, char *table)
return -1;
}
-static int
+static long
decodename(Biobuf *bp, Sym *p)
{
char *cp;
int c1, c2;
- int n;
+ long n;
+ vlong o;
if((p->type & 0x80) == 0) { /* old-style, fixed length names */
p->name = malloc(NNAME);
@@ -226,7 +222,7 @@ decodename(Biobuf *bp, Sym *p)
p->type &= ~0x80;
if(p->type == 'z' || p->type == 'Z') {
- n = Bseek(bp, 0, 1);
+ o = Bseek(bp, 0, 1);
if(Bgetc(bp) < 0) {
werrstr("can't read symbol name");
return -1;
@@ -241,15 +237,15 @@ decodename(Biobuf *bp, Sym *p)
if(c1 == 0 && c2 == 0)
break;
}
- n = Bseek(bp, 0, 1)-n;
+ n = Bseek(bp, 0, 1)-o;
p->name = malloc(n);
if(p->name == 0) {
- werrstr("can't malloc %d bytes", n);
+ werrstr("can't malloc %ld bytes", n);
return -1;
}
Bseek(bp, -n, 1);
if(Bread(bp, p->name, n) != n) {
- werrstr("can't read %d bytes of symbol name", n);
+ werrstr("can't read %ld bytes of symbol name", n);
return -1;
}
} else {
@@ -261,13 +257,14 @@ decodename(Biobuf *bp, Sym *p)
n = Blinelen(bp);
p->name = malloc(n);
if(p->name == 0) {
- werrstr("can't malloc %d bytes", n);
+ werrstr("can't malloc %ld bytes", n);
return -1;
}
strcpy(p->name, cp);
}
return n;
}
+
/*
* free any previously loaded symbol tables
*/
@@ -310,18 +307,18 @@ cleansyms(void)
if(pcline)
free(pcline);
pcline = 0;
- npcl = 0;
}
+
/*
* delimit the text segment
*/
void
-textseg(ulong base, Fhdr *fp)
+textseg(uvlong base, Fhdr *fp)
{
txtstart = base;
txtend = base+fp->txtsz;
- npcl = 0; /* all pcls must be recomputed */
}
+
/*
* symbase: return base and size of raw symbol table
* (special hack for high access rate operations)
@@ -332,13 +329,14 @@ symbase(long *n)
*n = nsym;
return symbols;
}
+
/*
* Get the ith symbol table entry
*/
Sym *
getsym(int index)
{
- if(index < nsym)
+ if(index >= 0 && index < nsym)
return &symbols[index];
return 0;
}
@@ -349,7 +347,8 @@ getsym(int index)
static int
buildtbls(void)
{
- int i, j, nh, ng, nt;
+ long i;
+ int j, nh, ng, nt;
File *f;
Txtsym *tp;
Hist *hp;
@@ -373,13 +372,12 @@ buildtbls(void)
return 0;
}
}
- fpmax++;
- fnames = malloc(fpmax*sizeof(*fnames));
+ fnames = malloc((fpmax+1)*sizeof(*fnames));
if (!fnames) {
werrstr("can't malloc file name table");
return 0;
}
- memset(fnames, 0, fpmax*sizeof(*fnames));
+ memset(fnames, 0, (fpmax+1)*sizeof(*fnames));
files = malloc(nfiles*sizeof(*files));
if(!files) {
werrstr("can't malloc file table");
@@ -409,7 +407,7 @@ buildtbls(void)
case 'B':
case 'b':
if(debug)
- fprint(2,"Global: %s %lux\n", p->name, p->value);
+ print("Global: %s %llux\n", p->name, p->value);
globals[ng++] = p;
break;
case 'z':
@@ -420,9 +418,10 @@ buildtbls(void)
hp += nh+1;
f++;
}
- else f = files;
+ else
+ f = files;
f->hist = hp;
- f->u0.fsym = 0;
+ f->sym = 0;
f->addr = 0;
nh = 0;
}
@@ -447,9 +446,9 @@ buildtbls(void)
tp->sym = p;
tp->locals = ap;
if(debug)
- fprint(2,"TEXT: %s at %lux\n", p->name, p->value);
- if(f && !f->u0.fsym) { /* first */
- f->u0.fsym = p;
+ print("TEXT: %s at %llux\n", p->name, p->value);
+ if(f && !f->sym) { /* first */
+ f->sym = p;
f->addr = p->value;
}
break;
@@ -457,10 +456,11 @@ buildtbls(void)
case 'p':
case 'm': /* Local Vars */
if(!tp)
- print("Warning: Free floating local var");
+ print("Warning: Free floating local var: %s\n",
+ p->name);
else {
if(debug)
- fprint(2,"Local: %s %lux\n", p->name, p->value);
+ print("Local: %s %llux\n", p->name, p->value);
tp->locals[tp->n] = p;
tp->n++;
ap++;
@@ -468,7 +468,7 @@ buildtbls(void)
break;
case 'f': /* File names */
if(debug)
- fprint(2,"Fname: %s\n", p->name);
+ print("Fname: %s\n", p->name);
fnames[p->value] = p;
break;
default:
@@ -482,12 +482,12 @@ buildtbls(void)
tp = txt;
for(i = 0, f = files; i < nfiles; i++, f++) {
for(j = 0; j < ntxt; j++) {
- if(f->u0.fsym == tp->sym) {
+ if(f->sym == tp->sym) {
if(debug) {
- fprint(2,"LINK: %s to at %lux", f->u0.fsym->name, f->addr);
+ print("LINK: %s to at %llux", f->sym->name, f->addr);
printhist("... ", f->hist, 1);
}
- f->u0.ftxt = tp++;
+ f->txt = tp++;
break;
}
if(++tp >= txt+ntxt) /* wrap around */
@@ -527,6 +527,7 @@ lookup(char *fn, char *var, Symbol *s)
return findglobal(var, s); /* case 3: var not found */
}
+
/*
* find a function by name
*/
@@ -539,6 +540,7 @@ findtext(char *name, Symbol *s)
if(strcmp(txt[i].sym->name, name) == 0) {
fillsym(txt[i].sym, s);
s->handle = (void *) &txt[i];
+ s->index = i;
return 1;
}
}
@@ -550,16 +552,18 @@ findtext(char *name, Symbol *s)
static int
findglobal(char *name, Symbol *s)
{
- int i;
+ long i;
for(i = 0; i < nglob; i++) {
if(strcmp(globals[i]->name, name) == 0) {
fillsym(globals[i], s);
+ s->index = i;
return 1;
}
}
return 0;
}
+
/*
* find the local variable by name within a given function
*/
@@ -572,6 +576,7 @@ findlocal(Symbol *s1, char *name, Symbol *s2)
return 0;
return findlocvar(s1, name, s2);
}
+
/*
* find the local variable by name within a given function
* (internal function - does no parameter validation)
@@ -588,11 +593,13 @@ findlocvar(Symbol *s1, char *name, Symbol *s2)
if (strcmp(tp->locals[i]->name, name) == 0) {
fillsym(tp->locals[i], s2);
s2->handle = (void *)tp;
+ s2->index = tp->n-1 - i;
return 1;
}
}
return 0;
}
+
/*
* Get ith text symbol
*/
@@ -602,12 +609,14 @@ textsym(Symbol *s, int index)
if(buildtbls() == 0)
return 0;
- if(index >= ntxt)
+ if(index < 0 || index >= ntxt)
return 0;
fillsym(txt[index].sym, s);
s->handle = (void *)&txt[index];
+ s->index = index;
return 1;
}
+
/*
* Get ith file name
*/
@@ -618,13 +627,14 @@ filesym(int index, char *buf, int n)
if(buildtbls() == 0)
return 0;
- if(index >= nfiles)
+ if(index < 0 || index >= nfiles)
return 0;
hp = files[index].hist;
if(!hp || !hp->name)
return 0;
return fileelem(fnames, (uchar*)hp->name, buf, n);
}
+
/*
* Lookup name of local variable located at an offset into the frame.
* The type selects either a parameter or automatic.
@@ -654,6 +664,7 @@ getauto(Symbol *s1, int off, int type, Symbol *s2)
if(p->type == t && p->value == off) {
fillsym(p, s2);
s2->handle = s1->handle;
+ s2->index = tp->n-1 - i;
return 1;
}
}
@@ -664,9 +675,9 @@ getauto(Symbol *s1, int off, int type, Symbol *s2)
* Find text symbol containing addr; binary search assumes text array is sorted by addr
*/
static int
-srchtext(long addr)
+srchtext(uvlong addr)
{
- ulong val;
+ uvlong val;
int top, bot, mid;
Sym *sp;
@@ -675,9 +686,9 @@ srchtext(long addr)
top = ntxt;
for (mid = (bot+top)/2; mid < top; mid = (bot+top)/2) {
sp = txt[mid].sym;
- if(val < (ulong)sp->value)
+ if(val < sp->value)
top = mid;
- else if(mid != ntxt-1 && val >= (ulong)txt[mid+1].sym->value)
+ else if(mid != ntxt-1 && val >= txt[mid+1].sym->value)
bot = mid;
else
return mid;
@@ -688,10 +699,10 @@ srchtext(long addr)
/*
* Find data symbol containing addr; binary search assumes data array is sorted by addr
*/
-static
-int srchdata(long addr)
+static int
+srchdata(uvlong addr)
{
- ulong val;
+ uvlong val;
int top, bot, mid;
Sym *sp;
@@ -700,15 +711,16 @@ int srchdata(long addr)
val = addr;
for(mid = (bot+top)/2; mid < top; mid = (bot+top)/2) {
sp = globals[mid];
- if(val < (ulong)sp->value)
+ if(val < sp->value)
top = mid;
- else if(mid < nglob-1 && val >= (ulong)globals[mid+1]->value)
+ else if(mid < nglob-1 && val >= globals[mid+1]->value)
bot = mid;
else
return mid;
}
return -1;
}
+
/*
* Find symbol containing val in specified search space
* There is a special case when a value falls beyond the end
@@ -717,7 +729,7 @@ int srchdata(long addr)
* data space are searched for a match.
*/
int
-findsym(long w, int type, Symbol *s)
+findsym(uvlong val, int type, Symbol *s)
{
int i;
@@ -725,19 +737,21 @@ findsym(long w, int type, Symbol *s)
return 0;
if(type == CTEXT || type == CANY) {
- i = srchtext(w);
+ i = srchtext(val);
if(i >= 0) {
if(type == CTEXT || i != ntxt-1) {
fillsym(txt[i].sym, s);
s->handle = (void *) &txt[i];
+ s->index = i;
return 1;
}
}
}
if(type == CDATA || type == CANY) {
- i = srchdata(w);
+ i = srchdata(val);
if(i >= 0) {
fillsym(globals[i], s);
+ s->index = i;
return 1;
}
}
@@ -748,7 +762,7 @@ findsym(long w, int type, Symbol *s)
* Find the start and end address of the function containing addr
*/
int
-fnbound(long addr, ulong *bounds)
+fnbound(uvlong addr, uvlong *bounds)
{
int i;
@@ -774,7 +788,7 @@ localsym(Symbol *s, int index)
{
Txtsym *tp;
- if(s == 0)
+ if(s == 0 || index < 0)
return 0;
if(buildtbls() == 0)
return 0;
@@ -783,10 +797,12 @@ localsym(Symbol *s, int index)
if(tp && tp->locals && index < tp->n) {
fillsym(tp->locals[tp->n-index-1], s); /* reverse */
s->handle = (void *)tp;
+ s->index = index;
return 1;
}
return 0;
}
+
/*
* get the ith global symbol
*/
@@ -798,30 +814,31 @@ globalsym(Symbol *s, int index)
if(buildtbls() == 0)
return 0;
- if(index < nglob) {
+ if(index >=0 && index < nglob) {
fillsym(globals[index], s);
+ s->index = index;
return 1;
}
return 0;
}
+
/*
* find the pc given a file name and line offset into it.
*/
-long
-file2pc(char *file, ulong line)
+uvlong
+file2pc(char *file, long line)
{
File *fp;
- int i;
- long pc;
- ulong start, end;
+ long i;
+ uvlong pc, start, end;
short *name;
if(buildtbls() == 0 || files == 0)
- return -1;
+ return ~0;
name = encfname(file);
if(name == 0) { /* encode the file name */
werrstr("file %s not found", file);
- return -1;
+ return ~0;
}
/* find this history stack */
for(i = 0, fp = files; i < nfiles; i++, fp++)
@@ -830,7 +847,7 @@ file2pc(char *file, ulong line)
free(name);
if(i >= nfiles) {
werrstr("line %ld in file %s not found", line, file);
- return -1;
+ return ~0;
}
start = fp->addr; /* first text addr this file */
if(i < nfiles-1)
@@ -842,14 +859,15 @@ file2pc(char *file, ulong line)
* run the state machine to locate the pc closest to that value.
*/
if(debug)
- fprint(2,"find pc for %ld - between: %lux and %lux\n", line, start, end);
+ print("find pc for %ld - between: %llux and %llux\n", line, start, end);
pc = line2addr(line, start, end);
- if(pc == -1) {
+ if(pc == ~0) {
werrstr("line %ld not in file %s", line, file);
- return -1;
+ return ~0;
}
return pc;
}
+
/*
* search for a path component index
*/
@@ -859,10 +877,11 @@ pathcomp(char *s, int n)
int i;
for(i = 0; i <= fpmax; i++)
- if(fnames[i] && strncmp(s, fnames[i]->name, n) == 0 && fnames[i]->name[n] == 0)
+ if(fnames[i] && strncmp(s, fnames[i]->name, n) == 0)
return i;
return -1;
}
+
/*
* Encode a char file name as a sequence of short indices
* into the file name dictionary.
@@ -900,12 +919,13 @@ encfname(char *file)
dest[i] = 0;
return dest;
}
+
/*
* Search a history stack for a matching file name accumulating
* the size of intervening files in the stack.
*/
static int
-hline(File *fp, short *name, ulong *line)
+hline(File *fp, short *name, long *line)
{
Hist *hp;
int offset, depth;
@@ -949,6 +969,7 @@ hline(File *fp, short *name, ulong *line)
*line = ln+offset;
return 1;
}
+
/*
* compare two encoded file names
*/
@@ -973,42 +994,19 @@ hcomp(Hist *hp, short *sp)
}
return *s == 0;
}
+
/*
* Convert a pc to a "file:line {file:line}" string.
*/
-int
-fileline(char *str, int n, ulong dot)
+long
+fileline(char *str, int n, uvlong dot)
{
- long line;
+ long line, top, bot, mid;
File *f;
- int i;
*str = 0;
if(buildtbls() == 0)
return 0;
-
- i = pc2filex(dot);
- if (i >= 0)
- {
- f = &files[i];
- line = pc2line(dot);
- if(line >= 0 && fline(str, n, line, f->hist, 0) >= 0)
- return 1;
- }
- return 0;
-}
-/*
- * Convert a pc to an index to the file table
- */
-static int
-pc2filex(ulong dot)
-{
- int top, bot, mid;
- File *f;
-
- if(buildtbls() == 0)
- return -1;
-
/* binary search assumes file list is sorted by addr */
bot = 0;
top = nfiles;
@@ -1018,10 +1016,14 @@ pc2filex(ulong dot)
top = mid;
else if(mid < nfiles-1 && dot >= (f+1)->addr)
bot = mid;
- else
- return mid;
+ else {
+ line = pc2line(dot);
+ if(line > 0 && fline(str, n, line, f->hist, 0) >= 0)
+ return 1;
+ break;
+ }
}
- return -1;
+ return 0;
}
/*
@@ -1034,7 +1036,7 @@ fline(char *str, int n, long line, Hist *base, Hist **ret)
{
Hist *start; /* start of current level */
Hist *h; /* current entry */
- int delta; /* sum of size of files this level */
+ long delta; /* sum of size of files this level */
int k;
start = base;
@@ -1056,9 +1058,8 @@ fline(char *str, int n, long line, Hist *base, Hist **ret)
}
}
} else {
- if(start == base) { /* end of recursion level */
- if(ret)
- *ret = h;
+ if(start == base && ret) { /* end of recursion level */
+ *ret = h;
return 1;
} else { /* end of included file */
delta += h->line-start->line;
@@ -1094,6 +1095,7 @@ fline(char *str, int n, long line, Hist *base, Hist **ret)
********************/
return 0;
}
+
/*
* convert an encoded file name to a string.
*/
@@ -1113,16 +1115,28 @@ fileelem(Sym **fp, uchar *cp, char *buf, int n)
*bp++ = *c++;
}
*bp = 0;
- return bp-buf;
+ i = bp-buf;
+ if(i > 1) {
+ cleanname(buf);
+ i = strlen(buf);
+ }
+ return i;
}
+
/*
* compare the values of two symbol table entries.
*/
static int
symcomp(void *a, void *b)
{
- return (*(Sym**)a)->value - (*(Sym**)b)->value;
+ int i;
+
+ i = (*(Sym**)a)->value - (*(Sym**)b)->value;
+ if (i)
+ return i;
+ return strcmp((*(Sym**)a)->name, (*(Sym**)b)->name);
}
+
/*
* compare the values of the symbols referenced by two text table entries
*/
@@ -1131,6 +1145,7 @@ txtcomp(void *a, void *b)
{
return ((Txtsym*)a)->sym->value - ((Txtsym*)b)->sym->value;
}
+
/*
* compare the values of the symbols referenced by two file table entries
*/
@@ -1139,6 +1154,7 @@ filecomp(void *a, void *b)
{
return ((File*)a)->addr - ((File*)b)->addr;
}
+
/*
* fill an interface Symbol structure from a symbol table entry
*/
@@ -1148,6 +1164,7 @@ fillsym(Sym *sp, Symbol *s)
s->type = sp->type;
s->value = sp->value;
s->name = sp->name;
+ s->index = 0;
switch(sp->type) {
case 'b':
case 'B':
@@ -1176,24 +1193,23 @@ fillsym(Sym *sp, Symbol *s)
}
s->handle = 0;
}
+
/*
* find the stack frame, given the pc
*/
-long
-pc2sp(ulong pc)
+uvlong
+pc2sp(uvlong pc)
{
- uchar *c;
- uchar u;
- ulong currpc;
- long currsp;
+ uchar *c, u;
+ uvlong currpc, currsp;
if(spoff == 0)
- return -1;
+ return ~0;
currsp = 0;
currpc = txtstart - mach->pcquant;
if(pc<currpc || pc>txtend)
- return -1;
+ return ~0;
for(c = spoff; c < spoffend; c++) {
if (currpc >= pc)
return currsp;
@@ -1210,76 +1226,29 @@ pc2sp(ulong pc)
currpc += mach->pcquant*(u-129);
currpc += mach->pcquant;
}
- return -1;
+ return ~0;
}
+
/*
* find the source file line number for a given value of the pc
*/
long
-pc2line(ulong pc)
-{
- File *fp;
- return pc2fline(pc, &fp);
-}
-/*
- * Convert a pc into a file table pointer & line offset
- */
-static long
-pc2fline(ulong pc, File **fpp)
+pc2line(uvlong pc)
{
- File *f;
- int i;
-
- i = pc2filex(pc);
- if (i < 0)
- return i;
- if (i >= npcl){
- /* Precompute starting points by file, else too slow */
- if (npcl == 0){
- Pcl pcl;
-
- /* decode start for pcline machine */
- pcl.pcline = pcline;
- pcl.pc = txtstart - mach->pcquant;
- pcl.line = 0;
- pcl2line(files->addr, &pcl, &files[0].pcl);
- npcl = 1;
- }
- for (f = &files[npcl]; npcl <= i; npcl++, f++)
- if (pcl2line(f->addr, &(f-1)->pcl, &f->pcl) < 0)
- break;
- }
- f = &files[i];
- *fpp = f;
- return pcl2line(pc, &f->pcl, 0);
-}
-/*
- * Convert pc to line offset, given Pcl starting point,
- * saving Pcl result.
- */
-static long
-pcl2line(ulong pc, Pcl *bp, Pcl *rp)
-{
- uchar *c;
- uchar u;
- ulong currpc;
+ uchar *c, u;
+ uvlong currpc;
long currline;
- if(bp->pcline == 0)
+ if(pcline == 0)
return -1;
- currpc = bp->pc;
- currline = bp->line;
+ currline = 0;
+ currpc = txtstart-mach->pcquant;
if(pc<currpc || pc>txtend)
- return -1;
- for(c = bp->pcline; c < pclineend; c++) {
- if (currpc >= pc) {
- if (rp){
- rp->pc = currpc;
- rp->line = currline;
- rp->pcline = c;
- }
+ return ~0;
+
+ for(c = pcline; c < pclineend; c++) {
+ if(currpc >= pc)
return currline;
- }
u = *c;
if(u == 0) {
currline += (c[1]<<24)|(c[2]<<16)|(c[3]<<8)|c[4];
@@ -1293,8 +1262,9 @@ pcl2line(ulong pc, Pcl *bp, Pcl *rp)
currpc += mach->pcquant*(u-129);
currpc += mach->pcquant;
}
- return -1;
+ return ~0;
}
+
/*
* find the pc associated with a line number
* basepc and endpc are text addresses bounding the search.
@@ -1302,22 +1272,21 @@ pcl2line(ulong pc, Pcl *bp, Pcl *rp)
* usually, basepc and endpc contain the first text address in
* a file and the first text address in the following file, respectively.
*/
-long
-line2addr(ulong line, ulong basepc, ulong endpc)
+uvlong
+line2addr(long line, uvlong basepc, uvlong endpc)
{
- uchar *c;
- uchar u;
- ulong currpc;
+ uchar *c, u;
+ uvlong currpc, pc;
long currline;
long delta, d;
- long pc, found;
+ int found;
if(pcline == 0 || line == 0)
- return -1;
+ return ~0;
currline = 0;
currpc = txtstart-mach->pcquant;
- pc = -1;
+ pc = ~0;
found = 0;
delta = HUGEINT;
@@ -1350,8 +1319,9 @@ line2addr(ulong line, ulong basepc, ulong endpc)
}
if(found)
return pc;
- return -1;
+ return ~0;
}
+
/*
* Print a history stack (debug). if count is 0, prints the whole stack
*/
@@ -1366,15 +1336,15 @@ printhist(char *msg, Hist *hp, int count)
while(hp->name) {
if(count && ++i > count)
break;
- fprint(2,"%s Line: %lx (%ld) Offset: %lx (%ld) Name: ", msg,
+ print("%s Line: %lx (%ld) Offset: %lx (%ld) Name: ", msg,
hp->line, hp->line, hp->offset, hp->offset);
for(cp = (uchar *)hp->name+1; (*cp<<8)|cp[1]; cp += 2) {
if (cp != (uchar *)hp->name+1)
- fprint(2,"/");
- fprint(2,"%x", (*cp<<8)|cp[1]);
+ print("/");
+ print("%x", (*cp<<8)|cp[1]);
}
fileelem(fnames, (uchar *) hp->name, buf, sizeof(buf));
- fprint(2," (%s)\n", buf);
+ print(" (%s)\n", buf);
hp++;
}
}