Annotation of kernel/uxkern/ux_exception.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /* 
                     26:  * Mach Operating System
                     27:  * Copyright (c) 1987 Carnegie-Mellon University
                     28:  * All rights reserved.  The CMU software License Agreement specifies
                     29:  * the terms and conditions for use and redistribution.
                     30:  */
                     31: 
                     32: /*
                     33:  *********************************************************************
                     34:  *
                     35:  *  1-Oct-87  David Black (dlb) at Carnegie-Mellon University
                     36:  *     Created
                     37:  *
                     38:  **********************************************************************
                     39:  */
                     40: 
                     41: #import <sys/param.h>
                     42: 
                     43: #import <mach/boolean.h>
                     44: #import <mach/exception.h>
                     45: #import <mach/kern_return.h>
                     46: #import <mach/message.h>
                     47: #import <mach/port.h>
                     48: #import <kern/task.h>
                     49: #import <kern/thread.h>
                     50: #import <sys/proc.h>
                     51: #import <sys/ux_exception.h>
                     52: #import <mach/mig_errors.h>
                     53: #import <kern/kalloc.h>
                     54: 
                     55: #import <mach/mach_user_internal.h>
                     56: 
                     57: #import <kern/sched_prim.h>
                     58: 
                     59: /*
                     60:  *     Unix exception handler.
                     61:  */
                     62: 
                     63: static void    ux_exception();
                     64: 
                     65: decl_simple_lock_data(static,  ux_handler_init_lock)
                     66: port_t                         ux_exception_port;
                     67: static port_t                  ux_handler_self;
                     68: 
                     69: static
                     70: void
                     71: ux_handler(void)
                     72: {
                     73:     task_t             self = current_task();
                     74:     port_name_t                exc_port_name;
                     75:     port_set_name_t    exc_set_name;
                     76: 
                     77: 
                     78:     self->kernel_vm_space = TRUE;
                     79:     ux_handler_self = task_self();
                     80: 
                     81:     simple_lock(&ux_handler_init_lock);
                     82: 
                     83:     /*
                     84:      * Allocate a port set that we will receive on.
                     85:      */
                     86:     if (port_set_allocate(ux_handler_self, &exc_set_name) != KERN_SUCCESS)
                     87:            panic("ux_handler: port_set_allocate failed");
                     88: 
                     89:     /*
                     90:      * Allocate an exception port and use object_copyin to
                     91:      * translate it to the global name.  Put it into the set.
                     92:      */
                     93:     if (port_allocate(ux_handler_self, &exc_port_name) != KERN_SUCCESS)
                     94:        panic("ux_handler: port_allocate failed");
                     95:     if (port_set_add(ux_handler_self,
                     96:                        exc_set_name, exc_port_name) != KERN_SUCCESS)
                     97:        panic("ux_handler: port_set_add failed");
                     98:     if (!object_copyin(self, exc_port_name,
                     99:                        MSG_TYPE_PORT, FALSE,
                    100:                        (void *) &ux_exception_port))
                    101:        panic("ux_handler: object_copyin(ux_exception_port) failed");
                    102: 
                    103:     /*
                    104:      * Release kernel to continue.
                    105:      */
                    106:     thread_wakeup(&ux_exception_port);
                    107:     simple_unlock(&ux_handler_init_lock);
                    108: 
                    109:     /* Message handling loop. */
                    110: 
                    111:     for (;;) {
                    112:        struct rep_msg {
                    113:            msg_header_t        h;
                    114:            int                 d[4];
                    115:        } rep_msg;
                    116:        struct exc_msg {
                    117:            msg_header_t        h;
                    118:            int                 d[16];  /* max is actually 10 */
                    119:        } exc_msg;
                    120:        port_t                  reply_port;
                    121:        msg_return_t            result;
                    122: 
                    123:        exc_msg.h.msg_local_port = exc_set_name;
                    124:        exc_msg.h.msg_size = sizeof (exc_msg);
                    125: 
                    126:        result = msg_receive(&exc_msg.h, MSG_OPTION_NONE, 0);
                    127: 
                    128:        if (result == RCV_SUCCESS) {
                    129:            reply_port = exc_msg.h.msg_remote_port;
                    130: 
                    131:            if (exc_server(&exc_msg.h, &rep_msg.h))
                    132:                (void) msg_send(&rep_msg.h, MSG_OPTION_NONE, 0);
                    133: 
                    134:            if (reply_port != PORT_NULL)
                    135:                (void) port_deallocate(ux_handler_self, reply_port);
                    136:        }
                    137:        else if (result == RCV_TOO_LARGE)
                    138:                /* ignore oversized messages */;
                    139:        else
                    140:                panic("exception_handler");
                    141:     }
                    142: }
                    143: 
                    144: void
                    145: ux_handler_init(void)
                    146: {
                    147:     task_t     handler_task;
                    148: 
                    149:     simple_lock_init(&ux_handler_init_lock);
                    150:     ux_exception_port = PORT_NULL;
                    151:     handler_task = kernel_task_create(kernel_task, 0);
                    152:     (void) kernel_thread(handler_task, ux_handler, (void *)0);
                    153:     simple_lock(&ux_handler_init_lock);
                    154:     if (ux_exception_port == PORT_NULL) 
                    155:            thread_sleep(&ux_exception_port,
                    156:                    simple_lock_addr(ux_handler_init_lock), FALSE);
                    157:     else
                    158:            simple_unlock(&ux_handler_init_lock);
                    159: }
                    160: 
                    161: kern_return_t
                    162: catch_exception_raise(
                    163:     port_t             exception_port,
                    164:     port_t             thread_name,
                    165:     port_t             task_name,
                    166:     int                        exception,
                    167:     int                        code,
                    168:     int                        subcode
                    169: )
                    170: {
                    171:     task_t             self = current_task();
                    172:     thread_t           thread;
                    173:     port_t             thread_port;
                    174:     kern_return_t      result = KERN_SUCCESS;
                    175:     int                        signal = 0;
                    176:     u_long             ucode = 0;
                    177: 
                    178:     /*
                    179:      * Convert local thread name to global port.
                    180:      */
                    181: 
                    182:     if (object_copyin(self, thread_name,
                    183:                       MSG_TYPE_PORT, FALSE,
                    184:                       (void *) &thread_port)) {
                    185: 
                    186:        thread = convert_port_to_thread(thread_port);
                    187:        port_release(thread_port);
                    188: 
                    189:        /*
                    190:         *      Catch bogus ports
                    191:         */
                    192:        if (thread != THREAD_NULL) {
                    193:     
                    194:            /*
                    195:             *  Convert exception to unix signal and code.
                    196:             */
                    197:            ux_exception(exception, code, subcode, &signal, &ucode);
                    198: 
                    199:            /*
                    200:             *  Send signal.
                    201:             */
                    202:            if (signal != 0)
                    203:                threadsignal(thread, signal, ucode);
                    204: 
                    205:            thread_deallocate(thread);
                    206:        }
                    207:        else
                    208:            result = KERN_INVALID_ARGUMENT;
                    209:     }
                    210:     else
                    211:        result = KERN_INVALID_ARGUMENT;
                    212: 
                    213:     /*
                    214:      * Delete our send rights to the task and thread ports.
                    215:      */
                    216:     (void) port_deallocate(ux_handler_self, task_name);
                    217:     (void) port_deallocate(ux_handler_self, thread_name);
                    218: 
                    219:     return (result);
                    220: }
                    221: 
                    222: 
                    223: boolean_t      machine_exception();
                    224: 
                    225: /*
                    226:  *     ux_exception translates a mach exception, code and subcode to
                    227:  *     a signal and u.u_code.  Calls machine_exception (machine dependent)
                    228:  *     to attempt translation first.
                    229:  */
                    230: 
                    231: static
                    232: void ux_exception(
                    233:     int                        exception,
                    234:     int                        code,
                    235:     int                        subcode,
                    236:     int                        *ux_signal,
                    237:     int                        *ux_code
                    238: )
                    239: {
                    240:     /*
                    241:      * Try machine-dependent translation first.
                    242:      */
                    243:     if (machine_exception(exception, code, subcode, ux_signal, ux_code))
                    244:        return;
                    245:        
                    246:     switch(exception) {
                    247: 
                    248:     case EXC_BAD_ACCESS:
                    249:        if (code == KERN_INVALID_ADDRESS)
                    250:            *ux_signal = SIGSEGV;
                    251:        else
                    252:            *ux_signal = SIGBUS;
                    253:        break;
                    254: 
                    255:        case EXC_BAD_INSTRUCTION:
                    256:            *ux_signal = SIGILL;
                    257:            break;
                    258: 
                    259:        case EXC_ARITHMETIC:
                    260:            *ux_signal = SIGFPE;
                    261:            break;
                    262: 
                    263:        case EXC_EMULATION:
                    264:            *ux_signal = SIGEMT;
                    265:            break;
                    266: 
                    267:        case EXC_SOFTWARE:
                    268:            switch (code) {
                    269: 
                    270:            case EXC_UNIX_BAD_SYSCALL:
                    271:                *ux_signal = SIGSYS;
                    272:                break;
                    273:            case EXC_UNIX_BAD_PIPE:
                    274:                *ux_signal = SIGPIPE;
                    275:                break;
                    276:            case EXC_UNIX_ABORT:
                    277:                *ux_signal = SIGABRT;
                    278:                break;
                    279:            }
                    280:            break;
                    281: 
                    282:        case EXC_BREAKPOINT:
                    283:            *ux_signal = SIGTRAP;
                    284:            break;
                    285:     }
                    286: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.