| /* go-trampoline.c -- allocate a trampoline for a nested function. |
| Copyright 2009 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. */ |
| /* In order to build a trampoline we need space which is both writable |
| and executable. We currently just allocate a whole page. This |
| needs to be more system dependent. */ |
| __go_allocate_trampoline (uintptr_t size, void *closure) |
| page_size = getpagesize (); |
| __go_assert (page_size >= size); |
| ret = __go_alloc (2 * page_size - 1); |
| ret = (void *) (((uintptr_t) ret + page_size - 1) |
| & ~ ((uintptr_t) page_size - 1)); |
| /* Because the garbage collector only looks at correct address |
| offsets, we need to ensure that it will see the closure |
| off = ((size + sizeof (void *) - 1) / sizeof (void *)) * sizeof (void *); |
| __go_assert (size + off + sizeof (void *) <= page_size); |
| __builtin_memcpy (ret + off, &closure, sizeof (void *)); |
| i = mprotect (ret, size, PROT_READ | PROT_WRITE | PROT_EXEC); |