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/protxcpp.c | |
| 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/protxcpp.c')
| -rw-r--r-- | mps/code/protxcpp.c | 215 |
1 files changed, 215 insertions, 0 deletions
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 | */ | ||