aboutsummaryrefslogtreecommitdiff
path: root/libgo/runtime/go-caller.c
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/runtime/go-caller.c')
-rw-r--r--libgo/runtime/go-caller.c60
1 files changed, 56 insertions, 4 deletions
diff --git a/libgo/runtime/go-caller.c b/libgo/runtime/go-caller.c
index d6901e0..2a24a50 100644
--- a/libgo/runtime/go-caller.c
+++ b/libgo/runtime/go-caller.c
@@ -25,6 +25,7 @@ struct caller
String fn;
String file;
intgo line;
+ intgo index;
};
/* Collect file/line information for a PC value. If this is called
@@ -45,6 +46,12 @@ callback (void *data, uintptr_t pc __attribute__ ((unused)),
c->file = runtime_gostringnocopy ((const byte *) filename);
c->line = lineno;
+ if (c->index == 0)
+ return 1;
+
+ if (c->index > 0)
+ --c->index;
+
return 0;
}
@@ -102,14 +109,17 @@ __go_get_backtrace_state ()
return back_state;
}
-/* Return function/file/line information for PC. */
+/* Return function/file/line information for PC. The index parameter
+ is the entry on the stack of inlined functions; -1 means the last
+ one. */
_Bool
-__go_file_line (uintptr pc, String *fn, String *file, intgo *line)
+__go_file_line (uintptr pc, int index, String *fn, String *file, intgo *line)
{
struct caller c;
runtime_memclr (&c, sizeof c);
+ c.index = index;
backtrace_pcinfo (__go_get_backtrace_state (), pc, callback,
error_callback, &c);
*fn = c.fn;
@@ -186,7 +196,7 @@ FuncForPC (uintptr_t pc)
intgo line;
uintptr_t val;
- if (!__go_file_line (pc, &fn, &file, &line))
+ if (!__go_file_line (pc, -1, &fn, &file, &line))
return NULL;
ret = (Func *) runtime_malloc (sizeof (*ret));
@@ -219,7 +229,7 @@ runtime_funcline_go (Func *f __attribute__((unused)), uintptr targetpc)
struct funcline_go_return ret;
String fn;
- if (!__go_file_line (targetpc, &fn, &ret.retfile, &ret.retline))
+ if (!__go_file_line (targetpc, -1, &fn, &ret.retfile, &ret.retline))
runtime_memclr (&ret, sizeof ret);
return ret;
}
@@ -245,3 +255,45 @@ runtime_funcentry_go (Func *f)
{
return f->entry;
}
+
+/* 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;
+}