Waldek Hebisch wrote:
Adriaan van Os wrote:
It crashes with a bus error KERN_PROTECTION FAILURE (0x0002) at call *%eax. The eax register points to the stack, so I fear the stack is marked non-executable. Whether this is a problem in the kernel, gcc or the linker, I have to find out. There is a Darwin linker option -allow_stack_execute, but it causes a linker error (undefined symbols: _main), which is another thing to find out why ...
Wow, I think we have a workaround !
[Darwin:~/gpc/testgpc/tramp] adriaan% gp tramp.pas --no-pic -Wl,-stack_addr,c0000000 -Wl,-stack_size,4000000
This instructs the Darwin linker to create a segment __UNIXSTACK and apparently the stack segment has the correct priviliges set, because "tramp" no longer crashes !
Correct way is to define ENABLE_EXECUTE_STACK in gcc-3.4.x/gcc/config/i386/darwin.h. The definition should be similar to definitions in gcc-3.4.x/gcc/config/sol2.h and gcc-3.4.x/gcc/config/netbsd.h
Yes, adding the netbsd definition to gcc-3.4.x/gcc/config/i386/darwin.h solves all trampoline problems.
/* 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); \ }
New testsuite results:
[Darwin:gcc/p/test] adriaan% make EXTRA_PFLAGS="--no-pic -read_only_relocs suppress" rm -f *.dat *.o *.s *.i *.gpi *.gpd *.gpc core a.out stderr.out *.exe testmake.tmp dummy.c dummy.pas dummy.out diff_cr*.tmp fixcr fixcr.exe rm -f todo/a.out todo/*.exe todo/*.o todo/*.s todo/*.i todo/*.gpi todo/*.gpd todo/core GP= PC="gpc" PFLAGS=" --autobuild -g -O3 -W -Wall -Wno-unused --no-pic -read_only_relocs suppress " PFLAGS_NO_PATHS="-g -O3 -W -Wall -Wno-unused --no-pic -read_only_relocs suppress " SRCDIR="." TEST_MAKE_FLAG=test-make-flag "./test_run" "*.pas" | tee test_log | "./test_sum" -d Test Run By adriaan on 2005-11-21 20:13:06 Native configuration is i686-apple-darwin8 (Darwin.local)
=== gpc tests ===
Running target any Running testsuite ...
UNSUPPORTED: agettext2test.pas UNSUPPORTED: agettexttest.pas UNSUPPORTED: aregextest.pas UNSUPPORTED: fjf165a.pas UNSUPPORTED: gmptest.pas FAIL: systemtest.pas
=== gpc Summary ===
# of tests 4965 # of expected passes 4959 # of unexpected failures 1 # of unsupported tests 5
gpc version 20051104, based on gcc-3.4.4
This means we now have a stable compiler for non-position independent code. The FSF compiler for powerpc-apple-darwin has -mdynamic-no-pic, but for i686-apple-darwin that switch is currently only in the Apple branch. Maybe I can port Apple's changes for -mdyamic-no-pic to gcc-3.4.4.
Regards,
Adriaan van Os