}
more = len(ci.callers) > 0
- f, file, line := funcframe(pc, i)
- if f == nil {
+ // Subtract 1 from PC to undo the 1 we added in callback in
+ // go-callers.c.
+ function, file, line := funcfileline(pc-1, int32(i))
+ if function == "" && file == "" {
return Frame{}, more
}
+ entry := funcentry(pc - 1)
+ f := &Func{name: function, entry: entry}
- entry := f.Entry()
xpc := pc
if xpc > entry {
xpc--
}
- function := f.Name()
-
frame = Frame{
PC: xpc,
Func: f,
// A Func represents a Go function in the running binary.
type Func struct {
- opaque struct{} // unexported field to disallow conversions
+ name string
+ entry uintptr
}
// FuncForPC returns a *Func describing the function that contains the
// given program counter address, or else nil.
-func FuncForPC(pc uintptr) *Func
+func FuncForPC(pc uintptr) *Func {
+ name, _, _ := funcfileline(pc, -1)
+ if name == "" {
+ return nil
+ }
+ entry := funcentry(pc)
+ return &Func{name: name, entry: entry}
+}
// Name returns the name of the function.
func (f *Func) Name() string {
- return funcname_go(f)
+ return f.name
}
// Entry returns the entry address of the function.
func (f *Func) Entry() uintptr {
- return funcentry_go(f)
+ return f.entry
}
// FileLine returns the file name and line number of the
// The result will not be accurate if pc is not a program
// counter within f.
func (f *Func) FileLine(pc uintptr) (file string, line int) {
- return funcline_go(f, pc)
+ _, file, line = funcfileline(pc, -1)
+ return file, line
}
-// implemented in symtab.c
-func funcline_go(*Func, uintptr) (string, int)
-func funcname_go(*Func) string
-func funcentry_go(*Func) uintptr
-func funcframe(uintptr, int) (*Func, string, int)
+// implemented in go-caller.c
+func funcfileline(uintptr, int32) (string, string, int)
+func funcentry(uintptr) uintptr
-/* go-caller.c -- runtime.Caller and runtime.FuncForPC for Go.
+/* go-caller.c -- look up function/file/line/entry info
Copyright 2009 The Go Authors. All rights reserved.
Use of this source code is governed by a BSD-style
struct caller_ret Caller (int n) __asm__ (GOSYM_PREFIX "runtime.Caller");
-Func *FuncForPC (uintptr_t) __asm__ (GOSYM_PREFIX "runtime.FuncForPC");
-
/* Implement runtime.Caller. */
struct caller_ret
return ret;
}
-/* Implement runtime.FuncForPC. */
+/* Look up the function name, file name, and line number for a PC. */
-Func *
-FuncForPC (uintptr_t pc)
-{
- Func *ret;
- String fn;
- String file;
- intgo line;
- uintptr_t val;
-
- if (!__go_file_line (pc, -1, &fn, &file, &line))
- return NULL;
-
- ret = (Func *) runtime_malloc (sizeof (*ret));
- ret->name = fn;
-
- if (__go_symbol_value (pc, &val))
- ret->entry = val;
- else
- ret->entry = 0;
-
- return ret;
-}
-
-/* Look up the file and line information for a PC within a
- function. */
-
-struct funcline_go_return
+struct funcfileline_return
{
+ String retfn;
String retfile;
intgo retline;
};
-struct funcline_go_return
-runtime_funcline_go (Func *f, uintptr targetpc)
- __asm__ (GOSYM_PREFIX "runtime.funcline_go");
+struct funcfileline_return
+runtime_funcfileline (uintptr targetpc, int32 index)
+ __asm__ (GOSYM_PREFIX "runtime.funcfileline");
-struct funcline_go_return
-runtime_funcline_go (Func *f __attribute__((unused)), uintptr targetpc)
+struct funcfileline_return
+runtime_funcfileline (uintptr targetpc, int32 index)
{
- struct funcline_go_return ret;
- String fn;
+ struct funcfileline_return ret;
- if (!__go_file_line (targetpc, -1, &fn, &ret.retfile, &ret.retline))
+ if (!__go_file_line (targetpc, index, &ret.retfn, &ret.retfile,
+ &ret.retline))
runtime_memclr (&ret, sizeof ret);
return ret;
}
-/* Return the name of a function. */
-String runtime_funcname_go (Func *f)
- __asm__ (GOSYM_PREFIX "runtime.funcname_go");
-
-String
-runtime_funcname_go (Func *f)
-{
- if (f == NULL)
- return runtime_gostringnocopy ((const byte *) "");
- return f->name;
-}
-
/* Return the entry point of a function. */
-uintptr runtime_funcentry_go(Func *f)
- __asm__ (GOSYM_PREFIX "runtime.funcentry_go");
+uintptr runtime_funcentry(uintptr)
+ __asm__ (GOSYM_PREFIX "runtime.funcentry");
uintptr
-runtime_funcentry_go (Func *f)
+runtime_funcentry (uintptr pc)
{
- return f->entry;
-}
+ uintptr val;
-/* Look up file and line information for Frames.Next. */
-
-struct funcframe_return
-{
- Func* retfunc;
- String retfile;
- intgo retline;
-};
-
-struct funcframe_return
-runtime_funcframe (uintptr pc, int index)
- __asm__ (GOSYM_PREFIX "runtime.funcframe");
-
-struct funcframe_return
-runtime_funcframe (uintptr pc, int index)
-{
- struct funcframe_return ret;
- String fn;
- Func* func;
- uintptr_t val;
-
- // Subtract 1 from PC to undo the 1 we added in callback in go-callers.c.
- --pc;
-
- if (!__go_file_line (pc, index, &fn, &ret.retfile, &ret.retline))
- runtime_memclr (&ret, sizeof ret);
- else
- {
- func = (Func *) runtime_malloc (sizeof (*func));
- func->name = fn;
-
- if (__go_symbol_value (pc, &val))
- func->entry = val;
- else
- func->entry = 0;
-
- ret.retfunc = func;
- }
-
- return ret;
+ if (!__go_symbol_value (pc, &val))
+ return 0;
+ return val;
}
typedef uint8 bool;
typedef uint8 byte;
-typedef struct Func Func;
typedef struct g G;
typedef struct mutex Lock;
typedef struct m M;
void* fwdsig;
};
-// Layout of in-memory per-function information prepared by linker
-// See http://golang.org/s/go12symtab.
-// Keep in sync with linker and with ../../libmach/sym.c
-// and with package debug/gosym.
-struct Func
-{
- String name;
- uintptr entry; // entry pc
-};
-
#ifdef GOOS_nacl
enum {
NaCl = 1,
void runtime_parsedebugvars(void)
__asm__(GOSYM_PREFIX "runtime.parsedebugvars");
void _rt0_go(void);
-void* runtime_funcdata(Func*, int32);
int32 runtime_setmaxthreads(int32);
G* runtime_timejump(void);
void runtime_iterate_finq(void (*callback)(FuncVal*, void*, const FuncType*, const PtrType*));