@@ -1,8 +1,8 @@ -/* This file is derived from gcc-2.6.3/libgcc2.c, section L_trampoline */ +/* This file is derived from the GCC sources. */ -/* Copyright (C) 1989, 1992, 1993, 1994 Free Software Foundation, Inc. +/* Copyright (C) 1989-2006 Free Software Foundation, Inc. This file is part of GNU CC. GNU CC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,17 +17,16 @@ You should have received a copy of the GNU General Public License along with GNU CC; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* Jump to a trampoline, loading the static chain address. */ +/* Taken from gcc-4.1.0/gcc/config/alpha/osf.h. */ #if defined (__alpha__) void -__enable_execute_stack (addr) - void *addr; +__enable_execute_stack (void *addr) { long size = getpagesize (); long mask = ~(size-1); char *page = (char *) (((long) addr) & mask); char *end = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); @@ -36,10 +35,129 @@ if (mprotect (page, end - page, 7) < 0) perror ("mprotect of trampoline code"); } #endif + +/* Taken from gcc-4.1.0/gcc/config/sparc/freebsd.h. */ + +#if defined (__sparc__) + +extern int sysctlbyname(const char *, void *, size_t *, void *, size_t); +static int need_enable_exec_stack; +static void check_enabling(void) __attribute__ ((constructor)); +static void check_enabling(void) +{ + int prot = 0; + size_t len = sizeof(prot); + + sysctlbyname ("kern.stackprot", &prot, &len, NULL, 0); + if (prot != 7) + need_enable_exec_stack = 1; +} +void __enable_execute_stack (void *addr) +{ + if (!need_enable_exec_stack) + return; + else { + /* 7 is PROT_READ | PROT_WRITE | PROT_EXEC */ + if (mprotect (addr, TRAMPOLINE_SIZE, 7) < 0) + perror ("mprotect of trampoline code"); + } +} + +#endif + +/* Taken from gcc-4.1.0/gcc/config/sol2.h. */ + +#if (defined (__sparc__) || defined (__i386__)) && defined(__svr4__) && defined(__sun) + +extern long sysconf(int); + +static int need_enable_exec_stack; + +static void check_enabling(void) __attribute__ ((constructor)); +static void check_enabling(void) +{ + int prot = (int) sysconf(515 /* _SC_STACK_PROT */); + if (prot != 7 /* STACK_PROT_RWX */) + need_enable_exec_stack = 1; +} + +void +__enable_execute_stack (void *addr) +{ + if (!need_enable_exec_stack) + return; + else { + long size = getpagesize (); + long mask = ~(size-1); + char *page = (char *) (((long) addr) & mask); + char *end = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); + + if (mprotect (page, end - page, 7 /* STACK_PROT_RWX */) < 0) + perror ("mprotect of trampoline code"); + } +} + +#endif + +/* Taken from gcc-4.1.0/gcc/config/openbsd.h. */ + +#if defined (__OpenBSD__) + +/* Stack is explicitly denied execution rights on OpenBSD platforms. */ +void +__enable_execute_stack (void *addr) +{ + long size = getpagesize (); + long mask = ~(size-1); + char *page = (char *) (((long) addr) & mask); + char *end = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); + + if (mprotect (page, end - page, PROT_READ | PROT_WRITE | PROT_EXEC) < 0) + perror ("mprotect of trampoline code"); +} + +#endif + +/* Taken from gcc-4.1.0/gcc/config/netbsd.h. */ + +#if defined (__NetBSD__) + +extern int __sysctl (int *, unsigned int, void *, size_t *, void *, size_t); + +void +__enable_execute_stack (void *addr) +{ + static int size; + static long mask; + + char *page, *end; + + if (size == 0) + { + int mib[2]; + size_t len; + + mib[0] = 6; /* CTL_HW */ + mib[1] = 7; /* HW_PAGESIZE */ + len = sizeof (size); + (void) __sysctl (mib, 2, &size, &len, NULL, 0); + mask = ~((long) size - 1); + } + + page = (char *) (((long) addr) & mask); + end = (char *) ((((long) (addr + TRAMPOLINE_SIZE)) & mask) + size); + + /* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */ + (void) mprotect (page, end - page, 7); +} + +#endif + +/* The rest is taken from gcc-2.6.3/libgcc2.c. */ #if defined (NeXT) && defined (__MACH__) /* Make stack executable so we can call trampolines on stack. This is called from INITIALIZE_TRAMPOLINE in next.h. */