diff options
Diffstat (limited to 'src/pkg/runtime/symtab.goc')
-rw-r--r-- | src/pkg/runtime/symtab.goc | 332 |
1 files changed, 0 insertions, 332 deletions
diff --git a/src/pkg/runtime/symtab.goc b/src/pkg/runtime/symtab.goc deleted file mode 100644 index 15e1d28fa..000000000 --- a/src/pkg/runtime/symtab.goc +++ /dev/null @@ -1,332 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Runtime symbol table parsing. -// See http://golang.org/s/go12symtab for an overview. - -package runtime -#include "runtime.h" -#include "defs_GOOS_GOARCH.h" -#include "os_GOOS.h" -#include "arch_GOARCH.h" -#include "malloc.h" -#include "funcdata.h" - -typedef struct Ftab Ftab; -struct Ftab -{ - uintptr entry; - uintptr funcoff; -}; - -extern byte pclntab[]; - -static Ftab *ftab; -static uintptr nftab; -static uint32 *filetab; -static uint32 nfiletab; - -static String end = { (uint8*)"end", 3 }; - -void -runtime·symtabinit(void) -{ - int32 i, j; - Func *f1, *f2; - - // See golang.org/s/go12symtab for header: 0xfffffffb, - // two zero bytes, a byte giving the PC quantum, - // and a byte giving the pointer width in bytes. - if(*(uint32*)pclntab != 0xfffffffb || pclntab[4] != 0 || pclntab[5] != 0 || pclntab[6] != PCQuantum || pclntab[7] != sizeof(void*)) { - runtime·printf("runtime: function symbol table header: %x %x\n", *(uint32*)pclntab, *(uint32*)(pclntab+4)); - runtime·throw("invalid function symbol table\n"); - } - - nftab = *(uintptr*)(pclntab+8); - ftab = (Ftab*)(pclntab+8+sizeof(void*)); - for(i=0; i<nftab; i++) { - // NOTE: ftab[nftab].entry is legal; it is the address beyond the final function. - if(ftab[i].entry > ftab[i+1].entry) { - f1 = (Func*)(pclntab + ftab[i].funcoff); - f2 = (Func*)(pclntab + ftab[i+1].funcoff); - runtime·printf("function symbol table not sorted by program counter: %p %s > %p %s", ftab[i].entry, runtime·funcname(f1), ftab[i+1].entry, i+1 == nftab ? "end" : runtime·funcname(f2)); - for(j=0; j<=i; j++) - runtime·printf("\t%p %s\n", ftab[j].entry, runtime·funcname((Func*)(pclntab + ftab[j].funcoff))); - runtime·throw("invalid runtime symbol table"); - } - } - - filetab = (uint32*)(pclntab + *(uint32*)&ftab[nftab].funcoff); - nfiletab = filetab[0]; -} - -static uint32 -readvarint(byte **pp) -{ - byte *p; - uint32 v; - int32 shift; - - v = 0; - p = *pp; - for(shift = 0;; shift += 7) { - v |= (*p & 0x7F) << shift; - if(!(*p++ & 0x80)) - break; - } - *pp = p; - return v; -} - -void* -runtime·funcdata(Func *f, int32 i) -{ - byte *p; - - if(i < 0 || i >= f->nfuncdata) - return nil; - p = (byte*)&f->nfuncdata + 4 + f->npcdata*4; - if(sizeof(void*) == 8 && ((uintptr)p & 4)) { - if(((uintptr)f & 4)) - runtime·printf("misaligned func %p\n", f); - p += 4; - } - return ((void**)p)[i]; -} - -static bool -step(byte **pp, uintptr *pc, int32 *value, bool first) -{ - uint32 uvdelta, pcdelta; - int32 vdelta; - - uvdelta = readvarint(pp); - if(uvdelta == 0 && !first) - return 0; - if(uvdelta&1) - uvdelta = ~(uvdelta>>1); - else - uvdelta >>= 1; - vdelta = (int32)uvdelta; - pcdelta = readvarint(pp) * PCQuantum; - *value += vdelta; - *pc += pcdelta; - return 1; -} - -// Return associated data value for targetpc in func f. -// (Source file is f->src.) -static int32 -pcvalue(Func *f, int32 off, uintptr targetpc, bool strict) -{ - byte *p; - uintptr pc; - int32 value; - - enum { - debug = 0 - }; - - // The table is a delta-encoded sequence of (value, pc) pairs. - // Each pair states the given value is in effect up to pc. - // The value deltas are signed, zig-zag encoded. - // The pc deltas are unsigned. - // The starting value is -1, the starting pc is the function entry. - // The table ends at a value delta of 0 except in the first pair. - if(off == 0) - return -1; - p = pclntab + off; - pc = f->entry; - value = -1; - - if(debug && !runtime·panicking) - runtime·printf("pcvalue start f=%s [%p] pc=%p targetpc=%p value=%d tab=%p\n", - runtime·funcname(f), f, pc, targetpc, value, p); - - while(step(&p, &pc, &value, pc == f->entry)) { - if(debug) - runtime·printf("\tvalue=%d until pc=%p\n", value, pc); - if(targetpc < pc) - return value; - } - - // If there was a table, it should have covered all program counters. - // If not, something is wrong. - if(runtime·panicking || !strict) - return -1; - runtime·printf("runtime: invalid pc-encoded table f=%s pc=%p targetpc=%p tab=%p\n", - runtime·funcname(f), pc, targetpc, p); - p = (byte*)f + off; - pc = f->entry; - value = -1; - - while(step(&p, &pc, &value, pc == f->entry)) - runtime·printf("\tvalue=%d until pc=%p\n", value, pc); - - runtime·throw("invalid runtime symbol table"); - return -1; -} - -static String unknown = { (uint8*)"?", 1 }; - -int8* -runtime·funcname(Func *f) -{ - if(f == nil || f->nameoff == 0) - return nil; - return (int8*)(pclntab + f->nameoff); -} - -static int32 -funcline(Func *f, uintptr targetpc, String *file, bool strict) -{ - int32 line; - int32 fileno; - - *file = unknown; - fileno = pcvalue(f, f->pcfile, targetpc, strict); - line = pcvalue(f, f->pcln, targetpc, strict); - if(fileno == -1 || line == -1 || fileno >= nfiletab) { - // runtime·printf("looking for %p in %S got file=%d line=%d\n", targetpc, *f->name, fileno, line); - return 0; - } - *file = runtime·gostringnocopy(pclntab + filetab[fileno]); - return line; -} - -int32 -runtime·funcline(Func *f, uintptr targetpc, String *file) -{ - return funcline(f, targetpc, file, true); -} - -int32 -runtime·funcspdelta(Func *f, uintptr targetpc) -{ - int32 x; - - x = pcvalue(f, f->pcsp, targetpc, true); - if(x&(sizeof(void*)-1)) - runtime·printf("invalid spdelta %d %d\n", f->pcsp, x); - return x; -} - -int32 -runtime·pcdatavalue(Func *f, int32 table, uintptr targetpc) -{ - if(table < 0 || table >= f->npcdata) - return -1; - return pcvalue(f, (&f->nfuncdata)[1+table], targetpc, true); -} - -int32 -runtime·funcarglen(Func *f, uintptr targetpc) -{ - if(targetpc == f->entry) - return 0; - return runtime·pcdatavalue(f, PCDATA_ArgSize, targetpc-PCQuantum); -} - -func funcline_go(f *Func, targetpc uintptr) (retfile String, retline int) { - // Pass strict=false here, because anyone can call this function, - // and they might just be wrong about targetpc belonging to f. - retline = funcline(f, targetpc, &retfile, false); -} - -func funcname_go(f *Func) (ret String) { - ret = runtime·gostringnocopy((uint8*)runtime·funcname(f)); -} - -func funcentry_go(f *Func) (ret uintptr) { - ret = f->entry; -} - -Func* -runtime·findfunc(uintptr addr) -{ - Ftab *f; - int32 nf, n; - - if(nftab == 0) - return nil; - if(addr < ftab[0].entry || addr >= ftab[nftab].entry) - return nil; - - // binary search to find func with entry <= addr. - f = ftab; - nf = nftab; - while(nf > 0) { - n = nf/2; - if(f[n].entry <= addr && addr < f[n+1].entry) - return (Func*)(pclntab + f[n].funcoff); - else if(addr < f[n].entry) - nf = n; - else { - f += n+1; - nf -= n+1; - } - } - - // can't get here -- we already checked above - // that the address was in the table bounds. - // this can only happen if the table isn't sorted - // by address or if the binary search above is buggy. - runtime·prints("findfunc unreachable\n"); - return nil; -} - -func FuncForPC(pc uintptr) (ret *Func) { - ret = runtime·findfunc(pc); -} - -static bool -hasprefix(String s, int8 *p) -{ - int32 i; - - for(i=0; i<s.len; i++) { - if(p[i] == 0) - return 1; - if(p[i] != s.str[i]) - return 0; - } - return p[i] == 0; -} - -static bool -contains(String s, int8 *p) -{ - int32 i; - - if(p[0] == 0) - return 1; - for(i=0; i<s.len; i++) { - if(s.str[i] != p[0]) - continue; - if(hasprefix((String){s.str + i, s.len - i}, p)) - return 1; - } - return 0; -} - -bool -runtime·showframe(Func *f, G *gp) -{ - static int32 traceback = -1; - String name; - - if(m->throwing > 0 && gp != nil && (gp == m->curg || gp == m->caughtsig)) - return 1; - if(traceback < 0) - traceback = runtime·gotraceback(nil); - name = runtime·gostringnocopy((uint8*)runtime·funcname(f)); - - // Special case: always show runtime.panic frame, so that we can - // see where a panic started in the middle of a stack trace. - // See golang.org/issue/5832. - if(name.len == 7+1+5 && hasprefix(name, "runtime.panic")) - return 1; - - return traceback > 1 || f != nil && contains(name, ".") && !hasprefix(name, "runtime."); -} |