Commit 84852fe2 authored by Austin Clements's avatar Austin Clements

Make the runtime correctly decode the symbol table history

stacks produced by whole-package compilation.

Fix some off-by-ones in PC/line table parsing.  Hopefully.

R=rsc
APPROVED=rsc
DELTA=42  (24 added, 6 deleted, 12 changed)
OCL=33250
CL=33293
parent ce9b379c
...@@ -1316,9 +1316,7 @@ pc2line(uvlong pc) ...@@ -1316,9 +1316,7 @@ pc2line(uvlong pc)
if(pc<currpc || pc>txtend) if(pc<currpc || pc>txtend)
return ~0; return ~0;
for(c = pcline; c < pclineend; c++) { for(c = pcline; c < pclineend && pc <= currpc; c++) {
if(currpc >= pc)
return currline;
u = *c; u = *c;
if(u == 0) { if(u == 0) {
currline += (c[1]<<24)|(c[2]<<16)|(c[3]<<8)|c[4]; currline += (c[1]<<24)|(c[2]<<16)|(c[3]<<8)|c[4];
...@@ -1332,7 +1330,7 @@ pc2line(uvlong pc) ...@@ -1332,7 +1330,7 @@ pc2line(uvlong pc)
currpc += mach->pcquant*(u-129); currpc += mach->pcquant*(u-129);
currpc += mach->pcquant; currpc += mach->pcquant;
} }
return ~0; return currline;
} }
/* /*
......
...@@ -186,41 +186,63 @@ makepath(byte *buf, int32 nbuf, byte *path) ...@@ -186,41 +186,63 @@ makepath(byte *buf, int32 nbuf, byte *path)
// walk symtab accumulating path names for use by pc/ln table. // walk symtab accumulating path names for use by pc/ln table.
// don't need the full generality of the z entry history stack because // don't need the full generality of the z entry history stack because
// there are no includes in go (and only sensible includes in our c). // there are no includes in go (and only sensible includes in our c);
// assume code only appear in top-level files.
static void static void
dosrcline(Sym *sym) dosrcline(Sym *sym)
{ {
static byte srcbuf[1000]; static byte srcbuf[1000];
static String srcstring; static struct {
static int32 lno, incstart; String srcstring;
static int32 nf, nhist; int32 aline;
int32 delta;
} files[200];
static int32 incstart;
static int32 nfunc, nfile, nhist;
Func *f; Func *f;
int32 i;
switch(sym->symtype) { switch(sym->symtype) {
case 't': case 't':
case 'T': case 'T':
if(strcmp(sym->name, (byte*)"etext") == 0) if(strcmp(sym->name, (byte*)"etext") == 0)
break; break;
f = &func[nf++]; f = &func[nfunc++];
f->src = srcstring; // find source file
f->ln0 += lno; for(i = 0; i < nfile - 1; i++) {
if (files[i+1].aline > f->ln0)
break;
}
f->src = files[i].srcstring;
f->ln0 -= files[i].delta;
break; break;
case 'z': case 'z':
if(sym->value == 1) { if(sym->value == 1) {
// entry for main source file for a new object. // entry for main source file for a new object.
makepath(srcbuf, sizeof srcbuf, sym->name+1); makepath(srcbuf, sizeof srcbuf, sym->name+1);
srcstring = gostring(srcbuf);
lno = 0;
nhist = 0; nhist = 0;
nfile = 0;
if(nfile == nelem(files))
continue;
files[nfile].srcstring = gostring(srcbuf);
files[nfile].aline = 0;
files[nfile++].delta = 0;
} else { } else {
// push or pop of included file. // push or pop of included file.
makepath(srcbuf, sizeof srcbuf, sym->name+1); makepath(srcbuf, sizeof srcbuf, sym->name+1);
if(srcbuf[0] != '\0') { if(srcbuf[0] != '\0') {
if(nhist++ == 0) if(nhist++ == 0)
incstart = sym->value; incstart = sym->value;
if(nhist == 0 && nfile < nelem(files)) {
// new top-level file
files[nfile].srcstring = gostring(srcbuf);
files[nfile].aline = sym->value;
// this is "line 0"
files[nfile++].delta = sym->value - 1;
}
}else{ }else{
if(--nhist == 0) if(--nhist == 0)
lno -= sym->value - incstart; files[nfile-1].delta += sym->value - incstart;
} }
} }
} }
...@@ -251,7 +273,7 @@ splitpcln(void) ...@@ -251,7 +273,7 @@ splitpcln(void)
f->pc0 = pc - PcQuant; f->pc0 = pc - PcQuant;
line = 0; line = 0;
for(; p < ep; p++) { for(; p < ep; p++) {
if(f < ef && pc >= (f+1)->entry) { if(f < ef && pc > (f+1)->entry) {
f->pcln.nel = p - f->pcln.array; f->pcln.nel = p - f->pcln.array;
f->pcln.cap = f->pcln.nel; f->pcln.cap = f->pcln.nel;
f++; f++;
...@@ -292,9 +314,7 @@ funcline(Func *f, uint64 targetpc) ...@@ -292,9 +314,7 @@ funcline(Func *f, uint64 targetpc)
ep = p + f->pcln.nel; ep = p + f->pcln.nel;
pc = f->pc0; pc = f->pc0;
line = f->ln0; line = f->ln0;
for(; p < ep; p++) { for(; p < ep && pc <= targetpc; p++) {
if(pc >= targetpc)
return line;
if(*p == 0) { if(*p == 0) {
line += (p[1]<<24) | (p[2]<<16) | (p[3]<<8) | p[4]; line += (p[1]<<24) | (p[2]<<16) | (p[3]<<8) | p[4];
p += 4; p += 4;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment