The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/mach/mach_task.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: mach_task.c,v 1.61 2006/11/16 01:32:44 christos Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Emmanuel Dreyfus
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *        This product includes software developed by the NetBSD
   21  *        Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 #include "opt_compat_darwin.h"
   40 
   41 #include <sys/cdefs.h>
   42 __KERNEL_RCSID(0, "$NetBSD: mach_task.c,v 1.61 2006/11/16 01:32:44 christos Exp $");
   43 
   44 #include <sys/types.h>
   45 #include <sys/param.h>
   46 #include <sys/exec.h>
   47 #include <sys/systm.h>
   48 #include <sys/proc.h>
   49 #include <sys/ktrace.h>
   50 #include <sys/resourcevar.h>
   51 #include <sys/malloc.h>
   52 #include <sys/sa.h>
   53 #include <sys/mount.h>
   54 #include <sys/ktrace.h>
   55 #include <sys/syscallargs.h>
   56 #include <sys/kauth.h>
   57 
   58 #include <uvm/uvm_extern.h>
   59 #include <uvm/uvm_param.h>
   60 
   61 #include <compat/mach/mach_types.h>
   62 #include <compat/mach/mach_message.h>
   63 #include <compat/mach/mach_clock.h>
   64 #include <compat/mach/mach_errno.h>
   65 #include <compat/mach/mach_exec.h>
   66 #include <compat/mach/mach_port.h>
   67 #include <compat/mach/mach_task.h>
   68 #include <compat/mach/mach_services.h>
   69 #include <compat/mach/mach_syscallargs.h>
   70 
   71 #ifdef COMPAT_DARWIN
   72 #include <compat/darwin/darwin_exec.h>
   73 #endif
   74 
   75 #define ISSET(t, f)     ((t) & (f))
   76 
   77 static void
   78 update_exception_port(struct mach_emuldata *, int exc, struct mach_port *);
   79 
   80 int
   81 mach_task_get_special_port(args)
   82         struct mach_trap_args *args;
   83 {
   84         mach_task_get_special_port_request_t *req = args->smsg;
   85         mach_task_get_special_port_reply_t *rep = args->rmsg;
   86         size_t *msglen = args->rsize;
   87         struct lwp *l = args->l;
   88         struct lwp *tl = args->tl;
   89         struct mach_emuldata *med;
   90         struct mach_right *mr;
   91 
   92         med = (struct mach_emuldata *)tl->l_proc->p_emuldata;
   93 
   94         switch (req->req_which_port) {
   95         case MACH_TASK_KERNEL_PORT:
   96                 mr = mach_right_get(med->med_kernel, l, MACH_PORT_TYPE_SEND, 0);
   97                 break;
   98 
   99         case MACH_TASK_HOST_PORT:
  100                 mr = mach_right_get(med->med_host, l, MACH_PORT_TYPE_SEND, 0);
  101                 break;
  102 
  103         case MACH_TASK_BOOTSTRAP_PORT:
  104                 mr = mach_right_get(med->med_bootstrap,
  105                     l, MACH_PORT_TYPE_SEND, 0);
  106                 break;
  107 
  108         case MACH_TASK_WIRED_LEDGER_PORT:
  109         case MACH_TASK_PAGED_LEDGER_PORT:
  110         default:
  111                 uprintf("mach_task_get_special_port(): unimpl. port %d\n",
  112                     req->req_which_port);
  113                 return mach_msg_error(args, EINVAL);
  114                 break;
  115         }
  116 
  117         *msglen = sizeof(*rep);
  118         mach_set_header(rep, req, *msglen);
  119         mach_add_port_desc(rep, mr->mr_name);
  120         mach_set_trailer(rep, *msglen);
  121 
  122         return 0;
  123 }
  124 
  125 int
  126 mach_ports_lookup(args)
  127         struct mach_trap_args *args;
  128 {
  129         mach_ports_lookup_request_t *req = args->smsg;
  130         mach_ports_lookup_reply_t *rep = args->rmsg;
  131         size_t *msglen = args->rsize;
  132         struct lwp *l = args->l;
  133         struct lwp *tl = args->tl;
  134         struct mach_emuldata *med;
  135         struct mach_right *mr;
  136         mach_port_name_t mnp[7];
  137         void *uaddr;
  138         int error;
  139         int count;
  140 
  141         /*
  142          * This is some out of band data sent with the reply. In the
  143          * encountered situation, the out of band data has always been null
  144          * filled. We have to see more of this in order to fully understand
  145          * how this trap works.
  146          */
  147         med = (struct mach_emuldata *)tl->l_proc->p_emuldata;
  148         mnp[0] = (mach_port_name_t)MACH_PORT_DEAD;
  149         mnp[3] = (mach_port_name_t)MACH_PORT_DEAD;
  150         mnp[5] = (mach_port_name_t)MACH_PORT_DEAD;
  151         mnp[6] = (mach_port_name_t)MACH_PORT_DEAD;
  152 
  153         mr = mach_right_get(med->med_kernel, l, MACH_PORT_TYPE_SEND, 0);
  154         mnp[MACH_TASK_KERNEL_PORT] = mr->mr_name;
  155         mr = mach_right_get(med->med_host, l, MACH_PORT_TYPE_SEND, 0);
  156         mnp[MACH_TASK_HOST_PORT] = mr->mr_name;
  157         mr = mach_right_get(med->med_bootstrap, l, MACH_PORT_TYPE_SEND, 0);
  158         mnp[MACH_TASK_BOOTSTRAP_PORT] = mr->mr_name;
  159 
  160         /*
  161          * On Darwin, the data seems always null...
  162          */
  163         uaddr = NULL;
  164         if ((error = mach_ool_copyout(l, &mnp[0],
  165             &uaddr, sizeof(mnp), MACH_OOL_TRACE)) != 0)
  166                 return mach_msg_error(args, error);
  167 
  168         count = 3; /* XXX Shouldn't this be 7? */
  169 
  170         *msglen = sizeof(*rep);
  171         mach_set_header(rep, req, *msglen);
  172         mach_add_ool_ports_desc(rep, uaddr, count);
  173 
  174         rep->rep_init_port_set_count = count;
  175 
  176         mach_set_trailer(rep, *msglen);
  177 
  178         return 0;
  179 }
  180 
  181 int
  182 mach_task_set_special_port(args)
  183         struct mach_trap_args *args;
  184 {
  185         mach_task_set_special_port_request_t *req = args->smsg;
  186         mach_task_set_special_port_reply_t *rep = args->rmsg;
  187         size_t *msglen = args->rsize;
  188         struct lwp *l = args->l;
  189         struct lwp *tl = args->tl;
  190         mach_port_t mn;
  191         struct mach_right *mr;
  192         struct mach_port *mp;
  193         struct mach_emuldata *med;
  194 
  195         mn = req->req_special_port.name;
  196 
  197         /* Null port ? */
  198         if (mn == 0)
  199                 return mach_msg_error(args, 0);
  200 
  201         /* Does the inserted port exists? */
  202         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == 0)
  203                 return mach_msg_error(args, EPERM);
  204 
  205         if (mr->mr_type == MACH_PORT_TYPE_DEAD_NAME)
  206                 return mach_msg_error(args, EINVAL);
  207 
  208         med = (struct mach_emuldata *)tl->l_proc->p_emuldata;
  209 
  210         switch (req->req_which_port) {
  211         case MACH_TASK_KERNEL_PORT:
  212                 mp = med->med_kernel;
  213                 med->med_kernel = mr->mr_port;
  214                 if (mr->mr_port != NULL)
  215                         MACH_PORT_REF(mr->mr_port);
  216                 MACH_PORT_UNREF(mp);
  217                 break;
  218 
  219         case MACH_TASK_HOST_PORT:
  220                 mp = med->med_host;
  221                 med->med_host = mr->mr_port;
  222                 if (mr->mr_port != NULL)
  223                         MACH_PORT_REF(mr->mr_port);
  224                 MACH_PORT_UNREF(mp);
  225                 break;
  226 
  227         case MACH_TASK_BOOTSTRAP_PORT:
  228                 mp = med->med_bootstrap;
  229                 med->med_bootstrap = mr->mr_port;
  230                 if (mr->mr_port != NULL)
  231                         MACH_PORT_REF(mr->mr_port);
  232                 MACH_PORT_UNREF(mp);
  233 #ifdef COMPAT_DARWIN
  234                 /*
  235                  * mach_init sets the bootstrap port for any new process.
  236                  */
  237                 {
  238                         struct darwin_emuldata *ded;
  239 
  240                         ded = tl->l_proc->p_emuldata;
  241                         if (ded->ded_fakepid == 1) {
  242                                 mach_bootstrap_port = med->med_bootstrap;
  243 #ifdef DEBUG_DARWIN
  244                                 printf("*** New bootstrap port %p, "
  245                                     "recv %p [%p]\n",
  246                                     mach_bootstrap_port,
  247                                     mach_bootstrap_port->mp_recv,
  248                                     mach_bootstrap_port->mp_recv->mr_sethead);
  249 #endif /* DEBUG_DARWIN */
  250                         }
  251                 }
  252 #endif /* COMPAT_DARWIN */
  253                 break;
  254 
  255         default:
  256                 uprintf("mach_task_set_special_port: unimplemented port %d\n",
  257                     req->req_which_port);
  258         }
  259 
  260         *msglen = sizeof(*rep);
  261         mach_set_header(rep, req, *msglen);
  262 
  263         rep->rep_retval = 0;
  264 
  265         mach_set_trailer(rep, *msglen);
  266 
  267         return 0;
  268 }
  269 
  270 int
  271 mach_task_threads(args)
  272         struct mach_trap_args *args;
  273 {
  274         mach_task_threads_request_t *req = args->smsg;
  275         mach_task_threads_reply_t *rep = args->rmsg;
  276         size_t *msglen = args->rsize;
  277         struct lwp *l = args->l;
  278         struct lwp *tl = args->tl;
  279         struct proc *tp = tl->l_proc;
  280         struct lwp *cl;
  281         struct mach_emuldata *med;
  282         struct mach_lwp_emuldata *mle;
  283         int error;
  284         void *uaddr;
  285         size_t size;
  286         int i = 0;
  287         struct mach_right *mr;
  288         mach_port_name_t *mnp;
  289 
  290         med = tp->p_emuldata;
  291         size = tp->p_nlwps * sizeof(*mnp);
  292         mnp = malloc(size, M_TEMP, M_WAITOK);
  293         uaddr = NULL;
  294 
  295         LIST_FOREACH(cl, &tp->p_lwps, l_sibling) {
  296                 mle = cl->l_emuldata;
  297                 mr = mach_right_get(mle->mle_kernel, l, MACH_PORT_TYPE_SEND, 0);
  298                 mnp[i++] = mr->mr_name;
  299         }
  300 
  301         /* This will free mnp */
  302         if ((error = mach_ool_copyout(l, mnp, &uaddr,
  303             size, MACH_OOL_TRACE|MACH_OOL_FREE)) != 0)
  304                 return mach_msg_error(args, error);
  305 
  306         *msglen = sizeof(*rep);
  307         mach_set_header(rep, req, *msglen);
  308         mach_add_ool_ports_desc(rep, uaddr, tp->p_nlwps);
  309 
  310         rep->rep_count = tp->p_nlwps;
  311 
  312         mach_set_trailer(rep, *msglen);
  313 
  314         return 0;
  315 }
  316 
  317 int
  318 mach_task_get_exception_ports(args)
  319         struct mach_trap_args *args;
  320 {
  321         mach_task_get_exception_ports_request_t *req = args->smsg;
  322         mach_task_get_exception_ports_reply_t *rep = args->rmsg;
  323         struct lwp *l = args->l;
  324         struct lwp *tl = args->tl;
  325         size_t *msglen = args->rsize;
  326         struct mach_emuldata *med;
  327         struct mach_right *mr;
  328         struct mach_exc_info *mei;
  329         int i, j, count;
  330 
  331         med = tl->l_proc->p_emuldata;
  332 
  333         /* It always returns an array of 32 ports even if only 9 can be used */
  334         count = sizeof(rep->rep_old_handler) / sizeof(rep->rep_old_handler[0]);
  335 
  336         mach_set_header(rep, req, *msglen);
  337 
  338         rep->rep_masks_count = count;
  339 
  340         j = 0;
  341         for (i = 0; i <= MACH_EXC_MAX; i++) {
  342                 if (med->med_exc[i] == NULL)
  343                         continue;
  344 
  345                 if (med->med_exc[i]->mp_datatype != MACH_MP_EXC_INFO) {
  346 #ifdef DIAGNOSTIC
  347                         printf("Exception port without mach_exc_info\n");
  348 #endif
  349                         continue;
  350                 }
  351                 mei = med->med_exc[i]->mp_data;
  352 
  353                 mr = mach_right_get(med->med_exc[i], l, MACH_PORT_TYPE_SEND, 0);
  354 
  355                 mach_add_port_desc(rep, mr->mr_name);
  356 
  357                 rep->rep_masks[j] = 1 << i;
  358                 rep->rep_old_behaviors[j] = mei->mei_behavior;
  359                 rep->rep_old_flavors[j] = mei->mei_flavor;
  360 
  361                 j++;
  362         }
  363 
  364         *msglen = sizeof(*rep);
  365         mach_set_trailer(rep, *msglen);
  366 
  367         return 0;
  368 }
  369 
  370 static void
  371 update_exception_port(med, exc, mp)
  372         struct mach_emuldata *med;
  373         int exc;
  374         struct mach_port *mp;
  375 {
  376         if (med->med_exc[exc] != NULL)
  377                 MACH_PORT_UNREF(med->med_exc[exc]);
  378         med->med_exc[exc] = mp;
  379         MACH_PORT_REF(mp);
  380 
  381         return;
  382 }
  383 
  384 int
  385 mach_task_set_exception_ports(args)
  386         struct mach_trap_args *args;
  387 {
  388         mach_task_set_exception_ports_request_t *req = args->smsg;
  389         mach_task_set_exception_ports_reply_t *rep = args->rmsg;
  390         struct lwp *l = args->l;
  391         struct lwp *tl = args->tl;
  392         size_t *msglen = args->rsize;
  393         struct mach_emuldata *med;
  394         mach_port_name_t mn;
  395         struct mach_right *mr;
  396         struct mach_port *mp;
  397         struct mach_exc_info *mei;
  398 
  399         mn = req->req_new_port.name;
  400         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_SEND)) == 0)
  401                 return mach_msg_error(args, EPERM);
  402 
  403         mp = mr->mr_port;
  404 #ifdef DIAGNOSTIC
  405         if ((mp->mp_datatype != MACH_MP_EXC_INFO) &&
  406             (mp->mp_datatype != MACH_MP_NONE))
  407                 printf("mach_task_set_exception_ports: data exists\n");
  408 #endif
  409         mei = malloc(sizeof(*mei), M_EMULDATA, M_WAITOK);
  410         mei->mei_flavor = req->req_flavor;
  411         mei->mei_behavior = req->req_behavior;
  412 
  413         mp->mp_data = mei;
  414         mp->mp_flags |= MACH_MP_DATA_ALLOCATED;
  415         mp->mp_datatype = MACH_MP_EXC_INFO;
  416 
  417         med = tl->l_proc->p_emuldata;
  418         if (req->req_mask & MACH_EXC_MASK_BAD_ACCESS)
  419                 update_exception_port(med, MACH_EXC_BAD_ACCESS, mp);
  420         if (req->req_mask & MACH_EXC_MASK_BAD_INSTRUCTION)
  421                 update_exception_port(med, MACH_EXC_BAD_INSTRUCTION, mp);
  422         if (req->req_mask & MACH_EXC_MASK_ARITHMETIC)
  423                 update_exception_port(med, MACH_EXC_ARITHMETIC, mp);
  424         if (req->req_mask & MACH_EXC_MASK_EMULATION)
  425                 update_exception_port(med, MACH_EXC_EMULATION, mp);
  426         if (req->req_mask & MACH_EXC_MASK_SOFTWARE)
  427                 update_exception_port(med, MACH_EXC_SOFTWARE, mp);
  428         if (req->req_mask & MACH_EXC_MASK_BREAKPOINT)
  429                 update_exception_port(med, MACH_EXC_BREAKPOINT, mp);
  430         if (req->req_mask & MACH_EXC_MASK_SYSCALL)
  431                 update_exception_port(med, MACH_EXC_SYSCALL, mp);
  432         if (req->req_mask & MACH_EXC_MASK_MACH_SYSCALL)
  433                 update_exception_port(med, MACH_EXC_MACH_SYSCALL, mp);
  434         if (req->req_mask & MACH_EXC_MASK_RPC_ALERT)
  435                 update_exception_port(med, MACH_EXC_RPC_ALERT, mp);
  436 
  437 #ifdef DEBUG_MACH
  438         if (req->req_mask & (MACH_EXC_ARITHMETIC |
  439             MACH_EXC_EMULATION | MACH_EXC_MASK_SYSCALL |
  440             MACH_EXC_MASK_MACH_SYSCALL | MACH_EXC_RPC_ALERT))
  441                 printf("mach_set_exception_ports: some exceptions are "
  442                     "not supported (mask %x)\n", req->req_mask);
  443 #endif
  444 
  445         *msglen = sizeof(*rep);
  446         mach_set_header(rep, req, *msglen);
  447 
  448         rep->rep_retval = 0;
  449 
  450         mach_set_trailer(rep, *msglen);
  451 
  452         return 0;
  453 }
  454 
  455 int
  456 mach_task_info(args)
  457         struct mach_trap_args *args;
  458 {
  459         mach_task_info_request_t *req = args->smsg;
  460         mach_task_info_reply_t *rep = args->rmsg;
  461         struct lwp *tl = args->tl;
  462         size_t *msglen = args->rsize;
  463         int count;
  464         struct proc *tp = tl->l_proc;
  465 
  466         switch(req->req_flavor) {
  467         case MACH_TASK_BASIC_INFO: {
  468                 struct mach_task_basic_info *mtbi;
  469                 struct rusage *ru;
  470 
  471                 count = sizeof(*mtbi) / sizeof(rep->rep_info[0]);
  472                 if (req->req_count < count)
  473                         return mach_msg_error(args, ENOBUFS);
  474 
  475                 ru = &tp->p_stats->p_ru;
  476                 mtbi = (struct mach_task_basic_info *)&rep->rep_info[0];
  477 
  478                 mtbi->mtbi_suspend_count = ru->ru_nvcsw + ru->ru_nivcsw;
  479                 mtbi->mtbi_virtual_size = ru->ru_ixrss;
  480                 mtbi->mtbi_resident_size = ru->ru_maxrss;
  481                 mtbi->mtbi_user_time.seconds = ru->ru_utime.tv_sec;
  482                 mtbi->mtbi_user_time.microseconds = ru->ru_utime.tv_usec;
  483                 mtbi->mtbi_system_time.seconds = ru->ru_stime.tv_sec;
  484                 mtbi->mtbi_system_time.microseconds = ru->ru_stime.tv_usec;
  485                 mtbi->mtbi_policy = 0;
  486 
  487                 *msglen = sizeof(*rep) - sizeof(rep->rep_info) + sizeof(*mtbi);
  488                 break;
  489         }
  490 
  491         /* XXX this is supposed to be about threads, not processes... */
  492         case MACH_TASK_THREAD_TIMES_INFO: {
  493                 struct mach_task_thread_times_info *mttti;
  494                 struct rusage *ru;
  495 
  496                 count = sizeof(*mttti) / sizeof(rep->rep_info[0]);
  497                 if (req->req_count < count)
  498                         return mach_msg_error(args, ENOBUFS);
  499 
  500                 ru = &tp->p_stats->p_ru;
  501                 mttti = (struct mach_task_thread_times_info *)&rep->rep_info[0];
  502 
  503                 mttti->mttti_user_time.seconds = ru->ru_utime.tv_sec;
  504                 mttti->mttti_user_time.microseconds = ru->ru_utime.tv_usec;
  505                 mttti->mttti_system_time.seconds = ru->ru_stime.tv_sec;
  506                 mttti->mttti_system_time.microseconds = ru->ru_stime.tv_usec;
  507 
  508                 *msglen = sizeof(*rep) - sizeof(rep->rep_info) + sizeof(*mttti);
  509                 break;
  510         }
  511 
  512         /* XXX a few statistics missing here */
  513         case MACH_TASK_EVENTS_INFO: {
  514                 struct mach_task_events_info *mtei;
  515                 struct rusage *ru;
  516 
  517                 count = sizeof(*mtei) / sizeof(rep->rep_info[0]);
  518                 if (req->req_count < count)
  519                         return mach_msg_error(args, ENOBUFS);
  520 
  521                 mtei = (struct mach_task_events_info *)&rep->rep_info[0];
  522                 ru = &tp->p_stats->p_ru;
  523 
  524                 mtei->mtei_faults = ru->ru_majflt;
  525                 mtei->mtei_pageins = ru->ru_minflt;
  526                 mtei->mtei_cow_faults = 0; /* XXX */
  527                 mtei->mtei_message_sent = ru->ru_msgsnd;
  528                 mtei->mtei_message_received = ru->ru_msgrcv;
  529                 mtei->mtei_syscalls_mach = 0; /* XXX */
  530                 mtei->mtei_syscalls_unix = 0; /* XXX */
  531                 mtei->mtei_csw = 0; /* XXX */
  532 
  533                 *msglen = sizeof(*rep) - sizeof(rep->rep_info) + sizeof(*mtei);
  534                 break;
  535         }
  536 
  537         default:
  538                 uprintf("mach_task_info: unsupported flavor %d\n",
  539                     req->req_flavor);
  540                 return mach_msg_error(args, EINVAL);
  541         };
  542 
  543         mach_set_header(rep, req, *msglen);
  544 
  545         rep->rep_count = count;
  546 
  547         mach_set_trailer(rep, *msglen);
  548 
  549         return 0;
  550 }
  551 
  552 int
  553 mach_task_suspend(args)
  554         struct mach_trap_args *args;
  555 {
  556         mach_task_suspend_request_t *req = args->smsg;
  557         mach_task_suspend_reply_t *rep = args->rmsg;
  558         size_t *msglen = args->rsize;
  559         struct lwp *tl = args->tl;
  560         struct lwp *lp;
  561         struct mach_emuldata *med;
  562         struct proc *tp = tl->l_proc;
  563 
  564         med = tp->p_emuldata;
  565         med->med_suspend++; /* XXX Mach also has a per thread semaphore */
  566 
  567         LIST_FOREACH(lp, &tp->p_lwps, l_sibling) {
  568                 switch(lp->l_stat) {
  569                 case LSONPROC:
  570                 case LSRUN:
  571                 case LSSLEEP:
  572                 case LSSUSPENDED:
  573                 case LSZOMB:
  574                 case LSDEAD:
  575                         break;
  576                 default:
  577                         return mach_msg_error(args, 0);
  578                         break;
  579                 }
  580         }
  581         proc_stop(tp, 0);
  582 
  583         *msglen = sizeof(*rep);
  584         mach_set_header(rep, req, *msglen);
  585 
  586         rep->rep_retval = 0;
  587 
  588         mach_set_trailer(rep, *msglen);
  589 
  590         return 0;
  591 }
  592 
  593 int
  594 mach_task_resume(args)
  595         struct mach_trap_args *args;
  596 {
  597         mach_task_resume_request_t *req = args->smsg;
  598         mach_task_resume_reply_t *rep = args->rmsg;
  599         size_t *msglen = args->rsize;
  600         struct lwp *tl = args->tl;
  601         struct mach_emuldata *med;
  602         struct proc *tp = tl->l_proc;
  603 
  604         med = tp->p_emuldata;
  605         med->med_suspend--; /* XXX Mach also has a per thread semaphore */
  606 #if 0
  607         if (med->med_suspend > 0)
  608                 return mach_msg_error(args, 0); /* XXX error code */
  609 #endif
  610 
  611         /* XXX We should also wake up the stopped thread... */
  612 #ifdef DEBUG_MACH
  613         printf("resuming pid %d\n", tp->p_pid);
  614 #endif
  615         (void)proc_unstop(tp);
  616 
  617         *msglen = sizeof(*rep);
  618         mach_set_header(rep, req, *msglen);
  619 
  620         rep->rep_retval = 0;
  621 
  622         mach_set_trailer(rep, *msglen);
  623 
  624         return 0;
  625 }
  626 
  627 int
  628 mach_task_terminate(args)
  629         struct mach_trap_args *args;
  630 {
  631         mach_task_resume_request_t *req = args->smsg;
  632         mach_task_resume_reply_t *rep = args->rmsg;
  633         size_t *msglen = args->rsize;
  634         struct lwp *tl = args->tl;
  635         struct sys_exit_args cup;
  636         register_t retval;
  637         int error;
  638 
  639 
  640         SCARG(&cup, rval) = 0;
  641         error = sys_exit(tl, &cup, &retval);
  642 
  643         *msglen = sizeof(*rep);
  644         mach_set_header(rep, req, *msglen);
  645 
  646         rep->rep_retval = native_to_mach_errno[error];
  647 
  648         mach_set_trailer(rep, *msglen);
  649 
  650         return 0;
  651 }
  652 
  653 int
  654 mach_sys_task_for_pid(struct lwp *l, void *v, register_t *retval)
  655 {
  656         struct mach_sys_task_for_pid_args /* {
  657                 syscallarg(mach_port_t) target_tport;
  658                 syscallarg(int) pid;
  659                 syscallarg(mach_port_t) *t;
  660         } */ *uap = v;
  661         struct mach_right *mr;
  662         struct mach_emuldata *med;
  663         struct proc *t;
  664         int error;
  665 
  666         /*
  667          * target_tport is used because the task may be on
  668          * a different host. (target_tport, pid) is unique.
  669          * We don't support multiple-host configuration
  670          * yet, so this parameter should be useless.
  671          * However, we still validate it.
  672          */
  673         if ((mr = mach_right_check(SCARG(uap, target_tport),
  674             l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
  675                 return EPERM;
  676 
  677         if ((t = pfind(SCARG(uap, pid))) == NULL)
  678                 return ESRCH;
  679 
  680         /* Allowed only if the UID match, if setuid, or if superuser */
  681         if ((kauth_cred_getuid(t->p_cred) != kauth_cred_getuid(l->l_cred) ||
  682             ISSET(t->p_flag, P_SUGID)) && (error = kauth_authorize_generic(l->l_cred,
  683             KAUTH_GENERIC_ISSUSER, &l->l_acflag)) != 0)
  684                             return (error);
  685 
  686         /* This will only work on a Mach process */
  687         if ((t->p_emul != &emul_mach) &&
  688 #ifdef COMPAT_DARWIN
  689             (t->p_emul != &emul_darwin) &&
  690 #endif
  691             1)
  692                 return EINVAL;
  693 
  694         med = t->p_emuldata;
  695 
  696         if ((mr = mach_right_get(med->med_kernel, l,
  697             MACH_PORT_TYPE_SEND, 0)) == NULL)
  698                 return EINVAL;
  699 
  700         if ((error = copyout(&mr->mr_name, SCARG(uap, t),
  701             sizeof(mr->mr_name))) != 0)
  702                 return error;
  703 
  704         return 0;
  705 }
  706 

Cache object: 91bfd57336f000bc5b81b4729794261f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.