diff options
author | Ben Cheng <bccheng@google.com> | 2013-03-28 11:14:20 -0700 |
---|---|---|
committer | Ben Cheng <bccheng@google.com> | 2013-03-28 12:40:33 -0700 |
commit | af0c51ac87ab2a87caa03fa108f0d164987a2764 (patch) | |
tree | 4b8b470f7c5b69642fdab8d0aa1fbc148d02196b /gcc-4.8/libgo/runtime/go-callers.c | |
parent | d87cae247d39ebf4f5a6bf25c932a14d2fdb9384 (diff) | |
download | toolchain_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.c | 126 |
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; +} |