diff options
| author | David Jones | 2005-03-04 15:37:12 +0000 |
|---|---|---|
| committer | David Jones | 2005-03-04 15:37:12 +0000 |
| commit | 46f968a022d54e39afaa4baeb0f16f1c5acdf6fc (patch) | |
| tree | 9d772f8fdb0a2a1efe0e258f191908e529e0c48d /mps/code | |
| parent | f08f9dd87f7806991cc43db70de2e0df2aca43bd (diff) | |
| download | emacs-46f968a022d54e39afaa4baeb0f16f1c5acdf6fc.tar.gz emacs-46f968a022d54e39afaa4baeb0f16f1c5acdf6fc.zip | |
Mps: implemented prot on os x.
Copied from Perforce
Change: 147629
ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
| -rw-r--r-- | mps/code/protxc.c | 135 | ||||
| -rw-r--r-- | mps/code/protxcpp.c | 215 | ||||
| -rw-r--r-- | mps/code/xcppgc.gmk | 2 |
3 files changed, 351 insertions, 1 deletions
diff --git a/mps/code/protxc.c b/mps/code/protxc.c new file mode 100644 index 00000000000..14b6155ee9a --- /dev/null +++ b/mps/code/protxc.c | |||
| @@ -0,0 +1,135 @@ | |||
| 1 | /* protfr.c: PROTECTION FOR FreeBSD | ||
| 2 | * | ||
| 3 | * $Id$ | ||
| 4 | * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. | ||
| 5 | * | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include "mpm.h" | ||
| 9 | |||
| 10 | #ifndef MPS_OS_FR | ||
| 11 | #error "protfr.c is FreeBSD specific, but MPS_OS_FR is not set" | ||
| 12 | #endif | ||
| 13 | #ifndef PROTECTION | ||
| 14 | #error "protfr.c implements protection, but PROTECTION is not set" | ||
| 15 | #endif | ||
| 16 | |||
| 17 | #include <limits.h> | ||
| 18 | #include <stddef.h> | ||
| 19 | #include <stdlib.h> | ||
| 20 | #include <sys/types.h> | ||
| 21 | #include <sys/mman.h> | ||
| 22 | |||
| 23 | SRCID(protfr, "$Id$"); | ||
| 24 | |||
| 25 | |||
| 26 | /* ProtSet -- set protection | ||
| 27 | * | ||
| 28 | * This is just a thin veneer on top of mprotect(2). | ||
| 29 | */ | ||
| 30 | |||
| 31 | void ProtSet(Addr base, Addr limit, AccessSet mode) | ||
| 32 | { | ||
| 33 | int flags; | ||
| 34 | int res; | ||
| 35 | |||
| 36 | AVER(sizeof(int) == sizeof(Addr)); /* should be redundant; will fail on Alpha */ | ||
| 37 | AVER(base < limit); | ||
| 38 | AVER(base != 0); | ||
| 39 | AVER(AddrOffset(base, limit) <= INT_MAX); /* should be redundant */ | ||
| 40 | |||
| 41 | #if 0 | ||
| 42 | /* .flags.trouble: This less strict version of flags (which allows write | ||
| 43 | * access unless explicitly told not to) caused mmqa test 37 to fail. | ||
| 44 | * This might be a bug in MPS, so for now we go with the stricter | ||
| 45 | * version that matches the Win32 implementation. */ | ||
| 46 | /* .flags.trouble.freebsd: the above comment was in the Linux version | ||
| 47 | * of this code; I haven't verified it for FreeBSD. */ | ||
| 48 | flags = 0; | ||
| 49 | if((mode & AccessREAD) == 0) | ||
| 50 | flags |= PROT_READ | PROT_EXEC; | ||
| 51 | if((mode & AccessWRITE) == 0) | ||
| 52 | flags |= PROT_WRITE; | ||
| 53 | #endif | ||
| 54 | flags = PROT_READ | PROT_WRITE | PROT_EXEC; | ||
| 55 | if((mode & AccessWRITE) != 0) | ||
| 56 | flags = PROT_READ | PROT_EXEC; | ||
| 57 | if((mode & AccessREAD) != 0) | ||
| 58 | flags = 0; | ||
| 59 | |||
| 60 | res = mprotect((void *)base, (size_t)AddrOffset(base, limit), flags); | ||
| 61 | AVER(res == 0); | ||
| 62 | } | ||
| 63 | |||
| 64 | |||
| 65 | /* ProtSync -- synchronize protection settings with hardware | ||
| 66 | * | ||
| 67 | * This does nothing under FreeBSD. | ||
| 68 | */ | ||
| 69 | |||
| 70 | void ProtSync(Arena arena) | ||
| 71 | { | ||
| 72 | NOOP; | ||
| 73 | } | ||
| 74 | |||
| 75 | |||
| 76 | |||
| 77 | /* ProtTramp -- protection trampoline | ||
| 78 | * | ||
| 79 | * The protection trampoline is trivial under FreeBSD, as there is | ||
| 80 | * nothing that needs to be done in the dynamic context of the mutator | ||
| 81 | * in order to catch faults. (Contrast this with Win32 Structured | ||
| 82 | * Exception Handling.) | ||
| 83 | */ | ||
| 84 | |||
| 85 | void ProtTramp(void **resultReturn, void *(*f)(void *, size_t), | ||
| 86 | void *p, size_t s) | ||
| 87 | { | ||
| 88 | AVER(resultReturn != NULL); | ||
| 89 | AVER(FUNCHECK(f)); | ||
| 90 | /* Can't check p and s as they are interpreted by the client */ | ||
| 91 | |||
| 92 | *resultReturn = (*f)(p, s); | ||
| 93 | } | ||
| 94 | |||
| 95 | |||
| 96 | /* C. COPYRIGHT AND LICENSE | ||
| 97 | * | ||
| 98 | * Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>. | ||
| 99 | * All rights reserved. This is an open source license. Contact | ||
| 100 | * Ravenbrook for commercial licensing options. | ||
| 101 | * | ||
| 102 | * Redistribution and use in source and binary forms, with or without | ||
| 103 | * modification, are permitted provided that the following conditions are | ||
| 104 | * met: | ||
| 105 | * | ||
| 106 | * 1. Redistributions of source code must retain the above copyright | ||
| 107 | * notice, this list of conditions and the following disclaimer. | ||
| 108 | * | ||
| 109 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 110 | * notice, this list of conditions and the following disclaimer in the | ||
| 111 | * documentation and/or other materials provided with the distribution. | ||
| 112 | * | ||
| 113 | * 3. Redistributions in any form must be accompanied by information on how | ||
| 114 | * to obtain complete source code for this software and any accompanying | ||
| 115 | * software that uses this software. The source code must either be | ||
| 116 | * included in the distribution or be available for no more than the cost | ||
| 117 | * of distribution plus a nominal fee, and must be freely redistributable | ||
| 118 | * under reasonable conditions. For an executable file, complete source | ||
| 119 | * code means the source code for all modules it contains. It does not | ||
| 120 | * include source code for modules or files that typically accompany the | ||
| 121 | * major components of the operating system on which the executable file | ||
| 122 | * runs. | ||
| 123 | * | ||
| 124 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||
| 125 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||
| 126 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | ||
| 127 | * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 128 | * COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 129 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 130 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
| 131 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
| 132 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 133 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| 134 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 135 | */ | ||
diff --git a/mps/code/protxcpp.c b/mps/code/protxcpp.c new file mode 100644 index 00000000000..44c95b25b7f --- /dev/null +++ b/mps/code/protxcpp.c | |||
| @@ -0,0 +1,215 @@ | |||
| 1 | /* protxcpp.c: PROTECTION FOR MAC OS X ON POWERPC | ||
| 2 | * | ||
| 3 | * $Header$ | ||
| 4 | * Copyright (c) 2001,2005 Ravenbrook Limited. See end of file for license. | ||
| 5 | * | ||
| 6 | * Most of this was copied from protso.c and modified. | ||
| 7 | * | ||
| 8 | * REFERENCES | ||
| 9 | * | ||
| 10 | * [PEM] "PowerPC Microprocessor Family: The Programming Environments for | ||
| 11 | * 32-bit Microprocessors", Motorola, 1997-01. MPCFPE32B/AD REV.1 | ||
| 12 | * | ||
| 13 | * [SIGNALH] /usr/include/sys/signal.h on drj's iBook (Mac OS X 10.3.8) | ||
| 14 | * | ||
| 15 | * [PPCUCH] /usr/include/ppc/ucontext.h | ||
| 16 | * | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include "mpm.h" | ||
| 20 | |||
| 21 | #ifndef MPS_OS_XC | ||
| 22 | #error "protxcpp.c is Mac OS X specific, but MPS_OS_XC is not set" | ||
| 23 | #endif | ||
| 24 | #ifndef MPS_ARCH_PP | ||
| 25 | #error "protxcpp.c is PowerPC specific, but MPS_ARCH_PP is not set" | ||
| 26 | #endif | ||
| 27 | #ifndef PROTECTION | ||
| 28 | #error "protxcpp.c implements protection, but PROTECTION is not set" | ||
| 29 | #endif | ||
| 30 | |||
| 31 | #include <signal.h> | ||
| 32 | #include <sys/ucontext.h> | ||
| 33 | |||
| 34 | #include <stdio.h> /* DO NOT SUBMIT */ | ||
| 35 | |||
| 36 | SRCID(protxcpp, "$Id$"); | ||
| 37 | |||
| 38 | /* The previously-installed signal action, as returned by */ | ||
| 39 | /* sigaction(3). See ProtSetup. */ | ||
| 40 | |||
| 41 | static struct sigaction sigNext; | ||
| 42 | |||
| 43 | /* sigHandle -- protection signal handler | ||
| 44 | * | ||
| 45 | * This is the signal handler installed by ProtSetup to deal with | ||
| 46 | * protection faults. It is installed on the SIGBUS signal. | ||
| 47 | * It decodes the protection fault details from the signal context | ||
| 48 | * and passes them to ArenaAccess, which attempts to handle the | ||
| 49 | * fault and remove its cause. If the fault is handled, then | ||
| 50 | * the handler returns and execution resumes. If it isn't handled, | ||
| 51 | * then sigHandle does its best to pass the signal on to the | ||
| 52 | * previously installed signal handler (sigNext). | ||
| 53 | * | ||
| 54 | * .sigh.addr: si_addr, on Darwin 7.8.0, is the address of the faulting | ||
| 55 | * instruction (by observation). [SIGNALH] says, in the declaration of | ||
| 56 | * siginfo_t, that this field should be the faulting instruction, but | ||
| 57 | * below that says that for SIGBUS it should be the faulting address). | ||
| 58 | * We grub around in the ucontext to find the PowerPC DAR register (See | ||
| 59 | * [PEM] 6-25, Table 6-9) which contains the faulting address. | ||
| 60 | * | ||
| 61 | * .sigh.limit: We throw away the limit information. | ||
| 62 | */ | ||
| 63 | |||
| 64 | static void sigHandle(int sig, siginfo_t *info, void *contextArg) | ||
| 65 | { | ||
| 66 | ucontext_t *ucontext; | ||
| 67 | |||
| 68 | AVER(sig == SIGBUS); | ||
| 69 | AVER(info != NULL); | ||
| 70 | |||
| 71 | ucontext = contextArg; | ||
| 72 | |||
| 73 | { | ||
| 74 | int i; | ||
| 75 | fprintf(stderr, "sigHandle.\n"); | ||
| 76 | |||
| 77 | for(i=0; i < sizeof *info; ++i) { | ||
| 78 | fprintf(stderr, "%02x", ((unsigned char *)info)[i]); | ||
| 79 | } | ||
| 80 | fprintf(stderr, "\n"); | ||
| 81 | fprintf(stderr, "signo: %d, code %d, addr %p\n", | ||
| 82 | info->si_signo, info->si_code, info->si_addr); | ||
| 83 | |||
| 84 | fprintf(stderr, "ucontext:\n"); | ||
| 85 | for(i=0; i < sizeof *ucontext; ++i) { | ||
| 86 | fprintf(stderr, "%02x ", ((unsigned char *)ucontext)[i]); | ||
| 87 | } | ||
| 88 | fprintf(stderr, "\n"); | ||
| 89 | fprintf(stderr, "uc_mcontext:\n"); | ||
| 90 | for(i=0; i< sizeof ucontext->uc_mcontext; ++i) { | ||
| 91 | fprintf(stderr, "%02x ", ((unsigned char *)&ucontext->uc_mcontext)[i]); | ||
| 92 | } | ||
| 93 | fprintf(stderr, "\n"); | ||
| 94 | fprintf(stderr, "uc_mcontext->es.dar: %08lx\n", | ||
| 95 | (unsigned long)ucontext->uc_mcontext->es.dar); | ||
| 96 | } | ||
| 97 | |||
| 98 | /* On OS X the si_code field does't appear to be useful. Protection | ||
| 99 | * faults appear as SIGBUS signals, and the only documented code for | ||
| 100 | * SIGBUS is BUS_ADRALN (invalid address alignment) which is what | ||
| 101 | * si_code is set to (it has value 1), even though the address is | ||
| 102 | * in fact aligned. | ||
| 103 | * On other platforms a test like info->si_code == SEGV_ACCERR appears | ||
| 104 | * here. */ | ||
| 105 | if(1) { | ||
| 106 | AccessSet mode; | ||
| 107 | Addr base, limit; | ||
| 108 | |||
| 109 | /* We dont't bother to determine the access mode (read, write, etc.) | ||
| 110 | * under OS X. It's possible that this information is available in | ||
| 111 | * the context structures. Needs more investigation. | ||
| 112 | */ | ||
| 113 | |||
| 114 | mode = AccessREAD | AccessWRITE; | ||
| 115 | |||
| 116 | /* We assume that the access is for one word at the address. */ | ||
| 117 | |||
| 118 | /* See [PPCUCH] */ | ||
| 119 | base = (Addr)ucontext->uc_mcontext->es.dar; | ||
| 120 | limit = AddrAdd(base, (Size)sizeof(Addr)); | ||
| 121 | |||
| 122 | /* Offer each protection structure the opportunity to handle the */ | ||
| 123 | /* exception. If it succeeds, then allow the mutator to continue. */ | ||
| 124 | |||
| 125 | /* MutatorFaultContext parameter is a dummy parameter for this */ | ||
| 126 | /* implementation */ | ||
| 127 | fprintf(stderr, "access: base: %08x mode: %08x\n", (unsigned)base, mode); | ||
| 128 | if(ArenaAccess(base, mode, NULL)) { | ||
| 129 | fprintf(stderr, "returning\n"); | ||
| 130 | return; | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | /* The exception was not handled by any known protection structure, */ | ||
| 135 | /* so throw it to the previously installed handler. */ | ||
| 136 | |||
| 137 | fprintf(stderr, "Throwing to %08x\n", (unsigned)sigNext.sa_sigaction); | ||
| 138 | |||
| 139 | /* @@ This is really weak. | ||
| 140 | * Need to implement rest of the contract of sigaction */ | ||
| 141 | (*sigNext.sa_sigaction)(sig, info, contextArg); | ||
| 142 | } | ||
| 143 | |||
| 144 | |||
| 145 | /* ProtSetup -- global protection setup | ||
| 146 | * | ||
| 147 | * Under OS X, the global setup involves installing a signal handler | ||
| 148 | * on SIGBUS to catch and handle protection faults (see sigHandle). | ||
| 149 | * The previous handler is recorded so that it can be reached from | ||
| 150 | * sigHandle if it fails to handle the fault. | ||
| 151 | * | ||
| 152 | * NOTE: There are problems with this approach: | ||
| 153 | * 1. we can't honor the wishes of the sigvec(2) entry for the | ||
| 154 | * previous handler, | ||
| 155 | */ | ||
| 156 | |||
| 157 | /* This function itself probably isn't architecture specific, but it | ||
| 158 | * references the sigHandle which is currently statis and which is | ||
| 159 | * architecture specific. */ | ||
| 160 | void ProtSetup(void) | ||
| 161 | { | ||
| 162 | struct sigaction sa; | ||
| 163 | int result; | ||
| 164 | |||
| 165 | sa.sa_sigaction = sigHandle; | ||
| 166 | /* No idea if sigemptyset is necessary, copied from protfri3.c, | ||
| 167 | * 2005-03-02 DRJ */ | ||
| 168 | sigemptyset(&sa.sa_mask); | ||
| 169 | sa.sa_flags = SA_SIGINFO; | ||
| 170 | |||
| 171 | result = sigaction(SIGBUS, &sa, &sigNext); | ||
| 172 | AVER(result == 0); | ||
| 173 | } | ||
| 174 | |||
| 175 | |||
| 176 | /* C. COPYRIGHT AND LICENSE | ||
| 177 | * | ||
| 178 | * Copyright (C) 2001-2002,2005 Ravenbrook Limited <http://www.ravenbrook.com/>. | ||
| 179 | * All rights reserved. This is an open source license. Contact | ||
| 180 | * Ravenbrook for commercial licensing options. | ||
| 181 | * | ||
| 182 | * Redistribution and use in source and binary forms, with or without | ||
| 183 | * modification, are permitted provided that the following conditions are | ||
| 184 | * met: | ||
| 185 | * | ||
| 186 | * 1. Redistributions of source code must retain the above copyright | ||
| 187 | * notice, this list of conditions and the following disclaimer. | ||
| 188 | * | ||
| 189 | * 2. Redistributions in binary form must reproduce the above copyright | ||
| 190 | * notice, this list of conditions and the following disclaimer in the | ||
| 191 | * documentation and/or other materials provided with the distribution. | ||
| 192 | * | ||
| 193 | * 3. Redistributions in any form must be accompanied by information on how | ||
| 194 | * to obtain complete source code for this software and any accompanying | ||
| 195 | * software that uses this software. The source code must either be | ||
| 196 | * included in the distribution or be available for no more than the cost | ||
| 197 | * of distribution plus a nominal fee, and must be freely redistributable | ||
| 198 | * under reasonable conditions. For an executable file, complete source | ||
| 199 | * code means the source code for all modules it contains. It does not | ||
| 200 | * include source code for modules or files that typically accompany the | ||
| 201 | * major components of the operating system on which the executable file | ||
| 202 | * runs. | ||
| 203 | * | ||
| 204 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||
| 205 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||
| 206 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR | ||
| 207 | * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE | ||
| 208 | * COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
| 209 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
| 210 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
| 211 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
| 212 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 213 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
| 214 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 215 | */ | ||
diff --git a/mps/code/xcppgc.gmk b/mps/code/xcppgc.gmk index 6ae29f5d5b9..637d774ea0d 100644 --- a/mps/code/xcppgc.gmk +++ b/mps/code/xcppgc.gmk | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | PFM = xcppgc | 6 | PFM = xcppgc |
| 7 | 7 | ||
| 8 | MPMPF = lockan.c than.c vmxc.c \ | 8 | MPMPF = lockan.c than.c vmxc.c \ |
| 9 | protan.c prmcan.c span.c | 9 | protxc.c protxcpp.c prmcan.c span.c |
| 10 | MPMS = ssxcpp.s | 10 | MPMS = ssxcpp.s |
| 11 | SWPF = than.c vmxc.c protsw.c prmcan.c ssan.c | 11 | SWPF = than.c vmxc.c protsw.c prmcan.c ssan.c |
| 12 | 12 | ||