Gale Paeper wrote:
Actually I had installed the patch Gale mentioned and actually there is a problem. For some reason under 10.5.2 the symbol __sysctl is not found but sysctl works. I therefore replaced __sysctl by sysctl in the patch and the build now proceeds to a new kind of problem:
That one I think is new with 10.5.2. Since Adriaan's supplied trampoline patch doesn't use __sysctl, I'm curious as to where the symbol __sysctl occurrence is located.
Yes, there may be a mix-up. The old trampoline patch *did* use __sysctl
# Waldek Hebisch hebisch@math.uni.wroc.pl & Adriaan van Os gpc@microbizz.nl # Fix trampolines on i386-apple-darwin, by making the stack executable (see # http://www.gnu-pascal.de/crystal/gpc/en/mail12945.html and # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24959)
diff -urN gcc-3.4.5-orig/gcc/config/i386/darwin.h gcc-3.4.5/gcc/config/i386/darwin.h --- gcc-3.4.5-orig/gcc/config/i386/darwin.h 2005-12-15 17:41:52.000000000 +0100 +++ gcc-3.4.5/gcc/config/i386/darwin.h 2005-12-17 15:31:03.000000000 +0100 @@ -137,3 +140,50 @@ } \ else fprintf (FILE, "\tcall mcount\n"); \ } while (0) + + +/* Attempt to turn on execute permission for the stack. This may be + used by INITIALIZE_TRAMPOLINE of the target needs it (that is, + if the target machine can change execute permissions on a page). + + There is no way to query the execute permission of the stack, so + we always issue the mprotect() call. + + Note that we go out of our way to use namespace-non-invasive calls + here. Unfortunately, there is no libc-internal name for mprotect(). + + Also note that no errors should be emitted by this code; it is considered + dangerous for library calls to send messages to stdout/stderr. */ + +#define ENABLE_EXECUTE_STACK \ +extern void __enable_execute_stack (void *); \ +void \ +__enable_execute_stack (void *addr) \ +{ \ + extern int mprotect (void *, size_t, int); \ + extern int __sysctl (int *, unsigned int, void *, size_t *, \ + void *, size_t); \ + \ + 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); \ +}
but it was changed for Mac OS X 10.5 *not* to use __sysctl, as follows
# Waldek Hebisch hebisch@math.uni.wroc.pl & Adriaan van Os gpc@microbizz.nl # Fix trampolines on i386-apple-darwin, by making the stack executable (see # http://www.gnu-pascal.de/crystal/gpc/en/mail12945.html and # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24959) # later modified by Geoffrey Keating # 2006-09-27 Geoffrey Keating geoffk@apple.com # avoid use of __sysctl on Darwin # see http://gcc.gnu.org/ml/gcc-patches/2006-09/msg01277.html # 20070922, and then backported to gcc-3.4.5 by Adriaan van Os gpc@microbizz.nl
diff -ur gcc-3.4.5-orig/gcc/config/i386/darwin.h gcc-3.4.5/gcc/config/i386/darwin.h --- gcc-3.4.5-orig/gcc/config/i386/darwin.h 2004-08-23 20:03:13.000000000 +0200 +++ gcc-3.4.5/gcc/config/i386/darwin.h 2007-09-23 13:22:24.000000000 +0200 @@ -137,3 +140,42 @@ } \ else fprintf (FILE, "\tcall mcount\n"); \ } while (0) + + +/* Attempt to turn on execute permission for the stack. This may be + used by INITIALIZE_TRAMPOLINE of the target needs it (that is, + if the target machine can change execute permissions on a page). + + There is no way to query the execute permission of the stack, so + we always issue the mprotect() call. + + Unfortunately it is not possible to make this namespace-clean. + + Also note that no errors should be emitted by this code; it is + considered dangerous for library calls to send messages to + stdout/stderr. */ + +#define ENABLE_EXECUTE_STACK \ +extern void __enable_execute_stack (void *); \ +void \ +__enable_execute_stack (void *addr) \ +{ \ + extern int mprotect (void *, size_t, int); \ + extern int getpagesize (void); \ + static int size; \ + static long mask; \ + \ + char *page, *end; \ + \ + if (size == 0) \ + { \ + size = getpagesize(); \ + mask = ~((long) size - 1); \ + } \ + \ + page = (char *) (((long) addr) & mask); \ + end = (char *) ((((long) (addr + (TARGET_64BIT ? 48 : 40))) & mask) + size); \ + \ + /* 7 == PROT_READ | PROT_WRITE | PROT_EXEC */ \ + (void) mprotect (page, end - page, 7); \ +}
Regards,
Adriaan van Os