diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-10-08 14:03:13 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-10-08 14:03:13 +0000 |
commit | db743d1833d4bd120783803d305bc7a6a527b1e1 (patch) | |
tree | d77929061927995d8e986e036e1f3492deb0e252 /libgo/go/reflect | |
parent | 400135ce934c52b755774d22e68b7d4f91711431 (diff) | |
download | gcc-db743d1833d4bd120783803d305bc7a6a527b1e1.tar.gz |
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/reflect')
-rw-r--r-- | libgo/go/reflect/makefunc_ffi_c.c | 27 |
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. */ |