From 84852fe220ba0980bd46f5828f50761e5f86c9d0 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Fri, 14 Aug 2009 14:36:49 -0700 Subject: [PATCH] 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 --- src/libmach/sym.c | 6 ++--- src/pkg/runtime/symtab.c | 48 ++++++++++++++++++++++++++++------------ 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/libmach/sym.c b/src/libmach/sym.c index 997cc06337..ad983041a6 100644 --- a/src/libmach/sym.c +++ b/src/libmach/sym.c @@ -1316,9 +1316,7 @@ pc2line(uvlong pc) if(pctxtend) return ~0; - for(c = pcline; c < pclineend; c++) { - if(currpc >= pc) - return currline; + for(c = pcline; c < pclineend && pc <= currpc; c++) { u = *c; if(u == 0) { currline += (c[1]<<24)|(c[2]<<16)|(c[3]<<8)|c[4]; @@ -1332,7 +1330,7 @@ pc2line(uvlong pc) currpc += mach->pcquant*(u-129); currpc += mach->pcquant; } - return ~0; + return currline; } /* diff --git a/src/pkg/runtime/symtab.c b/src/pkg/runtime/symtab.c index 7d7cc53126..6deb797f5e 100644 --- a/src/pkg/runtime/symtab.c +++ b/src/pkg/runtime/symtab.c @@ -186,41 +186,63 @@ makepath(byte *buf, int32 nbuf, byte *path) // walk symtab accumulating path names for use by pc/ln table. // 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 dosrcline(Sym *sym) { static byte srcbuf[1000]; - static String srcstring; - static int32 lno, incstart; - static int32 nf, nhist; + static struct { + String srcstring; + int32 aline; + int32 delta; + } files[200]; + static int32 incstart; + static int32 nfunc, nfile, nhist; Func *f; + int32 i; switch(sym->symtype) { case 't': case 'T': if(strcmp(sym->name, (byte*)"etext") == 0) break; - f = &func[nf++]; - f->src = srcstring; - f->ln0 += lno; + f = &func[nfunc++]; + // find source file + 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; case 'z': if(sym->value == 1) { // entry for main source file for a new object. makepath(srcbuf, sizeof srcbuf, sym->name+1); - srcstring = gostring(srcbuf); - lno = 0; nhist = 0; + nfile = 0; + if(nfile == nelem(files)) + continue; + files[nfile].srcstring = gostring(srcbuf); + files[nfile].aline = 0; + files[nfile++].delta = 0; } else { // push or pop of included file. makepath(srcbuf, sizeof srcbuf, sym->name+1); if(srcbuf[0] != '\0') { if(nhist++ == 0) 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{ if(--nhist == 0) - lno -= sym->value - incstart; + files[nfile-1].delta += sym->value - incstart; } } } @@ -251,7 +273,7 @@ splitpcln(void) f->pc0 = pc - PcQuant; line = 0; 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.cap = f->pcln.nel; f++; @@ -292,9 +314,7 @@ funcline(Func *f, uint64 targetpc) ep = p + f->pcln.nel; pc = f->pc0; line = f->ln0; - for(; p < ep; p++) { - if(pc >= targetpc) - return line; + for(; p < ep && pc <= targetpc; p++) { if(*p == 0) { line += (p[1]<<24) | (p[2]<<16) | (p[3]<<8) | p[4]; p += 4; -- 2.48.1