aboutsummaryrefslogtreecommitdiff
path: root/libgo/go
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2014-10-08 14:03:13 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>2014-10-08 14:03:13 +0000
commitdb743d1833d4bd120783803d305bc7a6a527b1e1 (patch)
treed77929061927995d8e986e036e1f3492deb0e252 /libgo/go
parent400135ce934c52b755774d22e68b7d4f91711431 (diff)
PR go/60406
runtime: Check callers in can_recover if return address doesn't match. Also use __builtin_extract_return_address and tighten up the checks in FFI code. Fixes PR 60406. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@216003 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/go')
-rw-r--r--libgo/go/reflect/makefunc_ffi_c.c27
1 files changed, 10 insertions, 17 deletions
diff --git a/libgo/go/reflect/makefunc_ffi_c.c b/libgo/go/reflect/makefunc_ffi_c.c
index fba269dcb58..a3dfd4acd2c 100644
--- a/libgo/go/reflect/makefunc_ffi_c.c
+++ b/libgo/go/reflect/makefunc_ffi_c.c
@@ -36,21 +36,23 @@ void ffiFree(void *data)
Go callback function (passed in user_data) with the pointer to the
arguments and the results area. */
+static void ffi_callback (ffi_cif *, void *, void **, void *)
+ __asm__ ("reflect.ffi_callback");
+
static void
ffi_callback (ffi_cif* cif __attribute__ ((unused)), void *results,
void **args, void *user_data)
{
- Location locs[6];
+ Location locs[8];
int n;
int i;
- const void *pc;
FuncVal *fv;
void (*f) (void *, void *);
/* This function is called from some series of FFI closure functions
- called by a Go function. We want to pass the PC of the Go
- function to makefunc_can_recover. Look up the stack for a
- function that is definitely not an FFI function. */
+ called by a Go function. We want to see whether the caller of
+ the closure functions can recover. Look up the stack and skip
+ the FFI functions. */
n = runtime_callers (1, &locs[0], sizeof locs / sizeof locs[0], true);
for (i = 0; i < n; i++)
{
@@ -61,28 +63,19 @@ ffi_callback (ffi_cif* cif __attribute__ ((unused)), void *results,
if (locs[i].function.len < 4)
break;
name = locs[i].function.str;
- if (*name == '_')
- {
- if (locs[i].function.len < 5)
- break;
- ++name;
- }
if (name[0] != 'f' || name[1] != 'f' || name[2] != 'i' || name[3] != '_')
break;
}
if (i < n)
- pc = (const void *) locs[i].pc;
- else
- pc = __builtin_return_address (0);
-
- __go_makefunc_can_recover (pc);
+ __go_makefunc_ffi_can_recover (locs + i, n - i);
fv = (FuncVal *) user_data;
__go_set_closure (fv);
f = (void *) fv->fn;
f (args, results);
- __go_makefunc_returning ();
+ if (i < n)
+ __go_makefunc_returning ();
}
/* Allocate an FFI closure and arrange to call ffi_callback. */