aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8/libgo/runtime/go-callers.c
diff options
context:
space:
mode:
authorBen Cheng <bccheng@google.com>2013-03-28 11:14:20 -0700
committerBen Cheng <bccheng@google.com>2013-03-28 12:40:33 -0700
commitaf0c51ac87ab2a87caa03fa108f0d164987a2764 (patch)
tree4b8b470f7c5b69642fdab8d0aa1fbc148d02196b /gcc-4.8/libgo/runtime/go-callers.c
parentd87cae247d39ebf4f5a6bf25c932a14d2fdb9384 (diff)
downloadtoolchain_gcc-af0c51ac87ab2a87caa03fa108f0d164987a2764.tar.gz
toolchain_gcc-af0c51ac87ab2a87caa03fa108f0d164987a2764.tar.bz2
toolchain_gcc-af0c51ac87ab2a87caa03fa108f0d164987a2764.zip
[GCC 4.8] Initial check-in of GCC 4.8.0
Change-Id: I0719d8a6d0f69b367a6ab6f10eb75622dbf12771
Diffstat (limited to 'gcc-4.8/libgo/runtime/go-callers.c')
-rw-r--r--gcc-4.8/libgo/runtime/go-callers.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/gcc-4.8/libgo/runtime/go-callers.c b/gcc-4.8/libgo/runtime/go-callers.c
new file mode 100644
index 000000000..dd1cf7909
--- /dev/null
+++ b/gcc-4.8/libgo/runtime/go-callers.c
@@ -0,0 +1,126 @@
+/* go-callers.c -- get callers for Go.
+
+ Copyright 2012 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. */
+
+#include "config.h"
+
+#include "backtrace.h"
+
+#include "runtime.h"
+#include "array.h"
+
+/* Argument passed to callback function. */
+
+struct callers_data
+{
+ Location *locbuf;
+ int skip;
+ int index;
+ int max;
+};
+
+/* Callback function for backtrace_full. Just collect the locations.
+ Return zero to continue, non-zero to stop. */
+
+static int
+callback (void *data, uintptr_t pc, const char *filename, int lineno,
+ const char *function)
+{
+ struct callers_data *arg = (struct callers_data *) data;
+ Location *loc;
+
+ /* Skip split stack functions. */
+ if (function != NULL)
+ {
+ const char *p;
+
+ p = function;
+ if (__builtin_strncmp (p, "___", 3) == 0)
+ ++p;
+ if (__builtin_strncmp (p, "__morestack_", 12) == 0)
+ return 0;
+ }
+ else if (filename != NULL)
+ {
+ const char *p;
+
+ p = strrchr (filename, '/');
+ if (p == NULL)
+ p = filename;
+ if (__builtin_strncmp (p, "/morestack.S", 12) == 0)
+ return 0;
+ }
+
+ if (arg->skip > 0)
+ {
+ --arg->skip;
+ return 0;
+ }
+
+ loc = &arg->locbuf[arg->index];
+ loc->pc = pc;
+
+ /* The libbacktrace library says that these strings might disappear,
+ but with the current implementation they won't. We can't easily
+ allocate memory here, so for now assume that we can save a
+ pointer to the strings. */
+ loc->filename = runtime_gostringnocopy ((const byte *) filename);
+ loc->function = runtime_gostringnocopy ((const byte *) function);
+
+ loc->lineno = lineno;
+ ++arg->index;
+ return arg->index >= arg->max;
+}
+
+/* Error callback. */
+
+static void
+error_callback (void *data __attribute__ ((unused)),
+ const char *msg, int errnum)
+{
+ if (errnum != 0)
+ runtime_printf ("%s errno %d\n", msg, errnum);
+ runtime_throw (msg);
+}
+
+/* Gather caller PC's. */
+
+int32
+runtime_callers (int32 skip, Location *locbuf, int32 m)
+{
+ struct callers_data data;
+
+ data.locbuf = locbuf;
+ data.skip = skip + 1;
+ data.index = 0;
+ data.max = m;
+ backtrace_full (__go_get_backtrace_state (), 0, callback, error_callback,
+ &data);
+ return data.index;
+}
+
+int Callers (int, struct __go_open_array)
+ __asm__ (GOSYM_PREFIX "runtime.Callers");
+
+int
+Callers (int skip, struct __go_open_array pc)
+{
+ Location *locbuf;
+ int ret;
+ int i;
+
+ locbuf = (Location *) runtime_mal (pc.__count * sizeof (Location));
+
+ /* In the Go 1 release runtime.Callers has an off-by-one error,
+ which we can not correct because it would break backward
+ compatibility. Normally we would add 1 to SKIP here, but we
+ don't so that we are compatible. */
+ ret = runtime_callers (skip, locbuf, pc.__count);
+
+ for (i = 0; i < ret; i++)
+ ((uintptr *) pc.__values)[i] = locbuf[i].pc;
+
+ return ret;
+}