Annotation of XNU/osfmk/ppc/bsd_ppc.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: #include <mach/mach_types.h>
                     23: #include <mach/exception_types.h>
                     24: #include <mach/error.h>
                     25: #include <kern/counters.h>
                     26: #include <kern/syscall_sw.h>
                     27: #include <kern/task.h>
                     28: #include <kern/thread.h>
                     29: #include <ppc/thread.h>
                     30: #include <kern/thread_act.h>
                     31: #include <ppc/thread_act.h>
                     32: #include <ppc/asm.h>
                     33: #include <ppc/proc_reg.h>
                     34: #include <ppc/trap.h>
                     35: #include <ppc/exception.h>
                     36: #include <kern/assert.h>
                     37: 
                     38: #include <sys/kdebug.h>
                     39: 
                     40: #define        ERESTART        -1              /* restart syscall */
                     41: #define        EJUSTRETURN     -2              /* don't modify regs, just return */
                     42: 
                     43: struct unix_syscallargs {
                     44:        int flavor;
                     45:        int r3;
                     46:        int arg1, arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9;
                     47: };
                     48: struct sysent {                /* system call table */
                     49:        unsigned short          sy_narg;                /* number of args */
                     50:        unsigned short          sy_parallel;    /* can execute in parallel */
                     51:        unsigned long           (*sy_call)(void *, void *, int *);      /* implementing function */
                     52: };
                     53: 
                     54: extern struct sysent sysent[];
                     55: 
                     56: void  *get_bsdtask_info(
                     57:        task_t);
                     58: 
                     59: int set_bsduthreadargs (
                     60:        thread_act_t, struct pcb *, 
                     61:        struct unix_syscallargs  *);
                     62: 
                     63: void * get_bsduthreadarg(
                     64:        thread_act_t);
                     65: 
                     66: void
                     67: unix_syscall(
                     68:        struct pcb * pcb,
                     69:     int, int, int, int, int, int, int );
                     70: 
                     71: /*
                     72:  * Function:   unix_syscall
                     73:  *
                     74:  * Inputs:     pcb     - pointer to Process Control Block
                     75:  *             arg1    - arguments to mach system calls
                     76:  *             arg2
                     77:  *             arg3
                     78:  *             arg4
                     79:  *             arg5
                     80:  *             arg6
                     81:  *             arg7
                     82:  *
                     83:  * Outputs:    none
                     84:  */
                     85: void
                     86: unix_syscall(
                     87:     struct pcb * pcb,
                     88:     int arg1,
                     89:     int arg2,
                     90:     int arg3,
                     91:     int arg4,
                     92:     int arg5,
                     93:     int arg6,
                     94:     int arg7 
                     95:     )
                     96: {
                     97:     struct ppc_saved_state     *regs;
                     98:     thread_act_t               thread;
                     99:     struct sysent              *callp;
                    100:     int                                nargs, error;
                    101:     unsigned short             code;
                    102:     void *  p, *vt;
                    103:     int * vtint;
                    104:        int *rval;
                    105: 
                    106:        struct unix_syscallargs sarg;
                    107:        extern int nsysent;
                    108: 
                    109:     (void) thread_set_funneled(TRUE);
                    110: 
                    111:     regs = &pcb->ss;
                    112:     thread = current_act();
                    113:        p = get_bsdtask_info(current_task());
                    114:        rval = (int *)get_bsduthreadrval(thread);
                    115: 
                    116:     /*
                    117:     ** Get index into sysent table
                    118:     */   
                    119:     code = regs->r0;
                    120: 
                    121:     
                    122:        /*
                    123:        ** Set up call pointer
                    124:        */
                    125:        callp = (code >= nsysent) ? &sysent[63] : &sysent[code];
                    126: 
                    127:        sarg. flavor = (callp == sysent)? 1: 0;
                    128:        if (sarg.flavor) {
                    129:                code = regs->r3;
                    130:                callp = (code >= nsysent) ? &sysent[63] : &sysent[code];
                    131: 
                    132:        }
                    133:        else 
                    134:                sarg. r3 = regs->r3;
                    135:        sarg. arg1 = arg1;
                    136:        sarg. arg2 = arg2;
                    137:        sarg. arg3 = arg3;
                    138:        sarg. arg4 = arg4;
                    139:        sarg. arg5 = arg5;
                    140:        sarg. arg6 = arg6;
                    141:        sarg. arg7 = arg7;
                    142: 
                    143:        set_bsduthreadargs(thread,pcb,&sarg);
                    144: 
                    145: 
                    146:        if (callp->sy_narg > 8)
                    147:        panic("unix_syscall: max arg count exceeded");
                    148: 
                    149:        rval[0] = 0;
                    150: 
                    151:        /* r4 is volatile, if we set it to regs->r4 here the child
                    152:         * will have parents r4 after execve */
                    153:        rval[1] = 0;
                    154: 
                    155:        error = 0; /* Start with a good value */
                    156: 
                    157:        /*
                    158:        ** the PPC runtime calls cerror after every unix system call, so
                    159:        ** assume no error and adjust the "pc" to skip this call.
                    160:        ** It will be set back to the cerror call if an error is detected.
                    161:        */
                    162:        regs->srr0 += 4;
                    163:        vt = get_bsduthreadarg(thread);
                    164: 
                    165:        if (code != 180) {
                    166:          vtint = (int *) vt;
                    167:          KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_START,
                    168:               vtint[0],vtint[1], vtint[2], vtint[3], 0);
                    169:        }
                    170:        
                    171:        counter_always(c_syscalls_unix++);
                    172:        current_task()->syscalls_unix++;
                    173:        error = (*(callp->sy_call))(p, (void *)vt, rval);
                    174: 
                    175:        if (code != 180) {
                    176:          KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_END,
                    177:                       error, rval[0], rval[1], 0, 0);
                    178:        }
                    179: 
                    180:     if (error == ERESTART) {
                    181:        regs->srr0 -= 8;
                    182:     }
                    183:     else if (error != EJUSTRETURN) {
                    184:        if (error)
                    185:        {
                    186:            regs->r3 = error;
                    187:            /* set the "pc" to execute cerror routine */
                    188:            regs->srr0 -= 4;
                    189:        } else { /* (not error) */
                    190:            regs->r3 = rval[0];
                    191:            regs->r4 = rval[1];
                    192:        } 
                    193:     }
                    194:     /* else  (error == EJUSTRETURN) { nothing } */
                    195: 
                    196:     (void) thread_set_funneled(FALSE);
                    197: 
                    198:     thread_exception_return();
                    199:     /* NOTREACHED */
                    200: }
                    201: 
                    202: unix_syscall_return(error)
                    203: {
                    204:     struct ppc_saved_state     *regs;
                    205:     thread_act_t               thread;
                    206:     struct sysent              *callp;
                    207:     int                                nargs;
                    208:     unsigned short             code;
                    209:        int *rval;
                    210:    void *  p, *vt;
                    211:     int * vtint;
                    212:        struct pcb *pcb;
                    213: 
                    214:        struct unix_syscallargs sarg;
                    215:        extern int nsysent;
                    216: 
                    217:     thread = current_act();
                    218:        p = get_bsdtask_info(current_task());
                    219:        rval = (int *)get_bsduthreadrval(thread);
                    220:        pcb = thread->mact.pcb;
                    221:     regs = &pcb->ss;
                    222: 
                    223:     /*
                    224:     ** Get index into sysent table
                    225:     */   
                    226:     code = regs->r0;
                    227: 
                    228:        if (code != 180) {
                    229:          KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_EXCP_SC, code) | DBG_FUNC_END,
                    230:                       error, rval[0], rval[1], 0, 0);
                    231:        }
                    232: 
                    233:     if (error == ERESTART) {
                    234:        regs->srr0 -= 8;
                    235:     }
                    236:     else if (error != EJUSTRETURN) {
                    237:        if (error)
                    238:        {
                    239:            regs->r3 = error;
                    240:            /* set the "pc" to execute cerror routine */
                    241:            regs->srr0 -= 4;
                    242:        } else { /* (not error) */
                    243:            regs->r3 = rval[0];
                    244:            regs->r4 = rval[1];
                    245:        } 
                    246:     }
                    247:     /* else  (error == EJUSTRETURN) { nothing } */
                    248: 
                    249:     (void) thread_set_funneled(FALSE);
                    250: 
                    251:     thread_exception_return();
                    252:     /* NOTREACHED */
                    253: }

unix.superglobalmegacorp.com

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