libgo patch committed: just do flie/line lookup in C, move Func to Go
Ian Lance Taylor
iant@golang.org
Fri Oct 14 17:20:00 GMT 2016
In order to port stack backtraces to Go, we need the ability to look
up file/line information for PC values without allocating memory.
This libgo patch moves the handling of Func from C code to Go code,
and simplifies the C code to just look up function/file/line/entry
information for a PC. Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu. Committed to mainline.
Ian
-------------- next part --------------
Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE (revision 241171)
+++ gcc/go/gofrontend/MERGE (working copy)
@@ -1,4 +1,4 @@
-911fceabd4c955b2f29f6b532f241a002ca7ad4f
+993840643e27e52cda7e86e6a775f54443ea5d07
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
Index: libgo/go/runtime/symtab.go
===================================================================
--- libgo/go/runtime/symtab.go (revision 240942)
+++ libgo/go/runtime/symtab.go (working copy)
@@ -65,19 +65,20 @@ func (ci *Frames) Next() (frame Frame, m
}
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,
@@ -97,21 +98,29 @@ func (ci *Frames) Next() (frame Frame, m
// 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
@@ -119,11 +128,10 @@ func (f *Func) Entry() uintptr {
// 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
Index: libgo/runtime/go-caller.c
===================================================================
--- libgo/runtime/go-caller.c (revision 240942)
+++ libgo/runtime/go-caller.c (working copy)
@@ -1,4 +1,4 @@
-/* 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
@@ -171,8 +171,6 @@ struct caller_ret
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
@@ -193,115 +191,40 @@ Caller (int skip)
return ret;
}
-/* Implement runtime.FuncForPC. */
-
-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. */
+/* Look up the function name, file name, and line number for a PC. */
-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;
-}
-
-/* Look up file and line information for Frames.Next. */
+ uintptr val;
-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;
}
Index: libgo/runtime/runtime.h
===================================================================
--- libgo/runtime/runtime.h (revision 241163)
+++ libgo/runtime/runtime.h (working copy)
@@ -55,7 +55,6 @@ typedef uintptr uintreg;
typedef uint8 bool;
typedef uint8 byte;
-typedef struct Func Func;
typedef struct g G;
typedef struct mutex Lock;
typedef struct m M;
@@ -153,16 +152,6 @@ struct SigTab
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,
@@ -446,7 +435,6 @@ void runtime_crash(void);
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*));
More information about the Gcc-patches
mailing list