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.54 2005/02/26 23:10:20 perry 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_ktrace.h"
   40 #include "opt_compat_darwin.h"
   41 
   42 #include <sys/cdefs.h>
   43 __KERNEL_RCSID(0, "$NetBSD: mach_task.c,v 1.54 2005/02/26 23:10:20 perry Exp $");
   44 
   45 #include <sys/types.h>
   46 #include <sys/param.h>
   47 #include <sys/exec.h>
   48 #include <sys/systm.h>
   49 #include <sys/proc.h>
   50 #include <sys/ktrace.h>
   51 #include <sys/resourcevar.h>
   52 #include <sys/malloc.h>
   53 #include <sys/sa.h>
   54 #include <sys/mount.h>
   55 #include <sys/ktrace.h>
   56 #include <sys/syscallargs.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 proc *p = l->l_proc;
  135         struct mach_emuldata *med;
  136         struct mach_right *mr;
  137         mach_port_name_t mnp[7];
  138         void *uaddr;
  139         int error;
  140         int count;
  141 
  142         /*
  143          * This is some out of band data sent with the reply. In the
  144          * encountered situation, the out of band data has always been null
  145          * filled. We have to see more of this in order to fully understand
  146          * how this trap works.
  147          */
  148         med = (struct mach_emuldata *)tl->l_proc->p_emuldata;
  149         mnp[0] = (mach_port_name_t)MACH_PORT_DEAD;
  150         mnp[3] = (mach_port_name_t)MACH_PORT_DEAD;
  151         mnp[5] = (mach_port_name_t)MACH_PORT_DEAD;
  152         mnp[6] = (mach_port_name_t)MACH_PORT_DEAD;
  153 
  154         mr = mach_right_get(med->med_kernel, l, MACH_PORT_TYPE_SEND, 0);
  155         mnp[MACH_TASK_KERNEL_PORT] = mr->mr_name;
  156         mr = mach_right_get(med->med_host, l, MACH_PORT_TYPE_SEND, 0);
  157         mnp[MACH_TASK_HOST_PORT] = mr->mr_name;
  158         mr = mach_right_get(med->med_bootstrap, l, MACH_PORT_TYPE_SEND, 0);
  159         mnp[MACH_TASK_BOOTSTRAP_PORT] = mr->mr_name;
  160 
  161         /*
  162          * On Darwin, the data seems always null...
  163          */
  164         uaddr = NULL;
  165         if ((error = mach_ool_copyout(p, &mnp[0],
  166             &uaddr, sizeof(mnp), MACH_OOL_TRACE)) != 0)
  167                 return mach_msg_error(args, error);
  168 
  169         count = 3; /* XXX Shouldn't this be 7? */
  170 
  171         *msglen = sizeof(*rep);
  172         mach_set_header(rep, req, *msglen);
  173         mach_add_ool_ports_desc(rep, uaddr, count);
  174 
  175         rep->rep_init_port_set_count = count;
  176 
  177         mach_set_trailer(rep, *msglen);
  178 
  179         return 0;
  180 }
  181 
  182 int
  183 mach_task_set_special_port(args)
  184         struct mach_trap_args *args;
  185 {
  186         mach_task_set_special_port_request_t *req = args->smsg;
  187         mach_task_set_special_port_reply_t *rep = args->rmsg;
  188         size_t *msglen = args->rsize;
  189         struct lwp *l = args->l;
  190         struct lwp *tl = args->tl;
  191         mach_port_t mn;
  192         struct mach_right *mr;
  193         struct mach_port *mp;
  194         struct mach_emuldata *med;
  195 
  196         mn = req->req_special_port.name;
  197 
  198         /* Null port ? */
  199         if (mn == 0)
  200                 return mach_msg_error(args, 0);
  201 
  202         /* Does the inserted port exists? */
  203         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_ALL_RIGHTS)) == 0)
  204                 return mach_msg_error(args, EPERM);
  205 
  206         if (mr->mr_type == MACH_PORT_TYPE_DEAD_NAME)
  207                 return mach_msg_error(args, EINVAL);
  208 
  209         med = (struct mach_emuldata *)tl->l_proc->p_emuldata;
  210 
  211         switch (req->req_which_port) {
  212         case MACH_TASK_KERNEL_PORT:
  213                 mp = med->med_kernel;
  214                 med->med_kernel = mr->mr_port;
  215                 if (mr->mr_port != NULL)
  216                         MACH_PORT_REF(mr->mr_port);
  217                 MACH_PORT_UNREF(mp);
  218                 break;
  219 
  220         case MACH_TASK_HOST_PORT:
  221                 mp = med->med_host;
  222                 med->med_host = mr->mr_port;
  223                 if (mr->mr_port != NULL)
  224                         MACH_PORT_REF(mr->mr_port);
  225                 MACH_PORT_UNREF(mp);
  226                 break;
  227 
  228         case MACH_TASK_BOOTSTRAP_PORT:
  229                 mp = med->med_bootstrap;
  230                 med->med_bootstrap = mr->mr_port;
  231                 if (mr->mr_port != NULL)
  232                         MACH_PORT_REF(mr->mr_port);
  233                 MACH_PORT_UNREF(mp);
  234 #ifdef COMPAT_DARWIN
  235                 /*
  236                  * mach_init sets the bootstrap port for any new process.
  237                  */
  238                 {
  239                         struct darwin_emuldata *ded;
  240 
  241                         ded = tl->l_proc->p_emuldata;
  242                         if (ded->ded_fakepid == 1) {
  243                                 mach_bootstrap_port = med->med_bootstrap;
  244 #ifdef DEBUG_DARWIN
  245                                 printf("*** New bootstrap port %p, "
  246                                     "recv %p [%p]\n",
  247                                     mach_bootstrap_port,
  248                                     mach_bootstrap_port->mp_recv,
  249                                     mach_bootstrap_port->mp_recv->mr_sethead);
  250 #endif /* DEBUG_DARWIN */
  251                         }
  252                 }
  253 #endif /* COMPAT_DARWIN */
  254                 break;
  255 
  256         default:
  257                 uprintf("mach_task_set_special_port: unimplemented port %d\n",
  258                     req->req_which_port);
  259         }
  260 
  261         *msglen = sizeof(*rep);
  262         mach_set_header(rep, req, *msglen);
  263 
  264         rep->rep_retval = 0;
  265 
  266         mach_set_trailer(rep, *msglen);
  267 
  268         return 0;
  269 }
  270 
  271 int
  272 mach_task_threads(args)
  273         struct mach_trap_args *args;
  274 {
  275         mach_task_threads_request_t *req = args->smsg;
  276         mach_task_threads_reply_t *rep = args->rmsg;
  277         size_t *msglen = args->rsize;
  278         struct lwp *l = args->l;
  279         struct lwp *tl = args->tl;
  280         struct proc *tp = tl->l_proc;
  281         struct lwp *cl;
  282         struct mach_emuldata *med;
  283         struct mach_lwp_emuldata *mle;
  284         int error;
  285         void *uaddr;
  286         size_t size;
  287         int i = 0;
  288         struct mach_right *mr;
  289         mach_port_name_t *mnp;
  290 
  291         med = tp->p_emuldata;
  292         size = tp->p_nlwps * sizeof(*mnp);
  293         mnp = malloc(size, M_TEMP, M_WAITOK);
  294         uaddr = NULL;
  295 
  296         LIST_FOREACH(cl, &tp->p_lwps, l_sibling) {
  297                 mle = cl->l_emuldata;
  298                 mr = mach_right_get(mle->mle_kernel, l, MACH_PORT_TYPE_SEND, 0);
  299                 mnp[i++] = mr->mr_name;
  300         }
  301 
  302         /* This will free mnp */
  303         if ((error = mach_ool_copyout(l->l_proc, mnp, &uaddr,
  304             size, MACH_OOL_TRACE|MACH_OOL_FREE)) != 0)
  305                 return mach_msg_error(args, error);
  306 
  307         *msglen = sizeof(*rep);
  308         mach_set_header(rep, req, *msglen);
  309         mach_add_ool_ports_desc(rep, uaddr, tp->p_nlwps);
  310 
  311         rep->rep_count = tp->p_nlwps;
  312 
  313         mach_set_trailer(rep, *msglen);
  314 
  315         return 0;
  316 }
  317 
  318 int
  319 mach_task_get_exception_ports(args)
  320         struct mach_trap_args *args;
  321 {
  322         mach_task_get_exception_ports_request_t *req = args->smsg;
  323         mach_task_get_exception_ports_reply_t *rep = args->rmsg;
  324         struct lwp *l = args->l;
  325         struct lwp *tl = args->tl;
  326         size_t *msglen = args->rsize;
  327         struct mach_emuldata *med;
  328         struct mach_right *mr;
  329         struct mach_exc_info *mei;
  330         int i, j, count;
  331 
  332         med = tl->l_proc->p_emuldata;
  333 
  334         /* It always returns an array of 32 ports even if only 9 can be used */
  335         count = sizeof(rep->rep_old_handler) / sizeof(rep->rep_old_handler[0]);
  336 
  337         mach_set_header(rep, req, *msglen);
  338 
  339         rep->rep_masks_count = count;
  340 
  341         j = 0;
  342         for (i = 0; i <= MACH_EXC_MAX; i++) {
  343                 if (med->med_exc[i] == NULL)
  344                         continue;
  345 
  346                 if (med->med_exc[i]->mp_datatype != MACH_MP_EXC_INFO) {
  347 #ifdef DIAGNOSTIC
  348                         printf("Exception port without mach_exc_info\n");
  349 #endif
  350                         continue;
  351                 }
  352                 mei = med->med_exc[i]->mp_data;
  353 
  354                 mr = mach_right_get(med->med_exc[i], l, MACH_PORT_TYPE_SEND, 0);
  355 
  356                 mach_add_port_desc(rep, mr->mr_name);
  357 
  358                 rep->rep_masks[j] = 1 << i;
  359                 rep->rep_old_behaviors[j] = mei->mei_behavior;
  360                 rep->rep_old_flavors[j] = mei->mei_flavor;
  361 
  362                 j++;
  363         }
  364 
  365         *msglen = sizeof(*rep);
  366         mach_set_trailer(rep, *msglen);
  367 
  368         return 0;
  369 }
  370 
  371 static void
  372 update_exception_port(med, exc, mp)
  373         struct mach_emuldata *med;
  374         int exc;
  375         struct mach_port *mp;
  376 {
  377         if (med->med_exc[exc] != NULL)
  378                 MACH_PORT_UNREF(med->med_exc[exc]);
  379         med->med_exc[exc] = mp;
  380         MACH_PORT_REF(mp);
  381 
  382         return;
  383 }
  384 
  385 int
  386 mach_task_set_exception_ports(args)
  387         struct mach_trap_args *args;
  388 {
  389         mach_task_set_exception_ports_request_t *req = args->smsg;
  390         mach_task_set_exception_ports_reply_t *rep = args->rmsg;
  391         struct lwp *l = args->l;
  392         struct lwp *tl = args->tl;
  393         size_t *msglen = args->rsize;
  394         struct mach_emuldata *med;
  395         mach_port_name_t mn;
  396         struct mach_right *mr;
  397         struct mach_port *mp;
  398         struct mach_exc_info *mei;
  399 
  400         mn = req->req_new_port.name;
  401         if ((mr = mach_right_check(mn, l, MACH_PORT_TYPE_SEND)) == 0)
  402                 return mach_msg_error(args, EPERM);
  403 
  404         mp = mr->mr_port;
  405 #ifdef DIAGNOSTIC
  406         if ((mp->mp_datatype != MACH_MP_EXC_INFO) &&
  407             (mp->mp_datatype != MACH_MP_NONE))
  408                 printf("mach_task_set_exception_ports: data exists\n");
  409 #endif
  410         mei = malloc(sizeof(*mei), M_EMULDATA, M_WAITOK);
  411         mei->mei_flavor = req->req_flavor;
  412         mei->mei_behavior = req->req_behavior;
  413 
  414         mp->mp_data = mei;
  415         mp->mp_flags |= MACH_MP_DATA_ALLOCATED;
  416         mp->mp_datatype = MACH_MP_EXC_INFO;
  417 
  418         med = tl->l_proc->p_emuldata;
  419         if (req->req_mask & MACH_EXC_MASK_BAD_ACCESS)
  420                 update_exception_port(med, MACH_EXC_BAD_ACCESS, mp);
  421         if (req->req_mask & MACH_EXC_MASK_BAD_INSTRUCTION)
  422                 update_exception_port(med, MACH_EXC_BAD_INSTRUCTION, mp);
  423         if (req->req_mask & MACH_EXC_MASK_ARITHMETIC)
  424                 update_exception_port(med, MACH_EXC_ARITHMETIC, mp);
  425         if (req->req_mask & MACH_EXC_MASK_EMULATION)
  426                 update_exception_port(med, MACH_EXC_EMULATION, mp);
  427         if (req->req_mask & MACH_EXC_MASK_SOFTWARE)
  428                 update_exception_port(med, MACH_EXC_SOFTWARE, mp);
  429         if (req->req_mask & MACH_EXC_MASK_BREAKPOINT)
  430                 update_exception_port(med, MACH_EXC_BREAKPOINT, mp);
  431         if (req->req_mask & MACH_EXC_MASK_SYSCALL)
  432                 update_exception_port(med, MACH_EXC_SYSCALL, mp);
  433         if (req->req_mask & MACH_EXC_MASK_MACH_SYSCALL)
  434                 update_exception_port(med, MACH_EXC_MACH_SYSCALL, mp);
  435         if (req->req_mask & MACH_EXC_MASK_RPC_ALERT)
  436                 update_exception_port(med, MACH_EXC_RPC_ALERT, mp);
  437 
  438 #ifdef DEBUG_MACH
  439         if (req->req_mask & (MACH_EXC_ARITHMETIC |
  440             MACH_EXC_EMULATION | MACH_EXC_MASK_SYSCALL |
  441             MACH_EXC_MASK_MACH_SYSCALL | MACH_EXC_RPC_ALERT))
  442                 printf("mach_set_exception_ports: some exceptions are "
  443                     "not supported (mask %x)\n", req->req_mask);
  444 #endif
  445 
  446         *msglen = sizeof(*rep);
  447         mach_set_header(rep, req, *msglen);
  448 
  449         rep->rep_retval = 0;
  450 
  451         mach_set_trailer(rep, *msglen);
  452 
  453         return 0;
  454 }
  455 
  456 int
  457 mach_task_info(args)
  458         struct mach_trap_args *args;
  459 {
  460         mach_task_info_request_t *req = args->smsg;
  461         mach_task_info_reply_t *rep = args->rmsg;
  462         struct lwp *tl = args->tl;
  463         size_t *msglen = args->rsize;
  464         int count;
  465         struct proc *tp = tl->l_proc;
  466 
  467         switch(req->req_flavor) {
  468         case MACH_TASK_BASIC_INFO: {
  469                 struct mach_task_basic_info *mtbi;
  470                 struct rusage *ru;
  471 
  472                 count = sizeof(*mtbi) / sizeof(rep->rep_info[0]);
  473                 if (req->req_count < count)
  474                         return mach_msg_error(args, ENOBUFS);
  475 
  476                 ru = &tp->p_stats->p_ru;
  477                 mtbi = (struct mach_task_basic_info *)&rep->rep_info[0];
  478 
  479                 mtbi->mtbi_suspend_count = ru->ru_nvcsw + ru->ru_nivcsw;
  480                 mtbi->mtbi_virtual_size = ru->ru_ixrss;
  481                 mtbi->mtbi_resident_size = ru->ru_maxrss;
  482                 mtbi->mtbi_user_time.seconds = ru->ru_utime.tv_sec;
  483                 mtbi->mtbi_user_time.microseconds = ru->ru_utime.tv_usec;
  484                 mtbi->mtbi_system_time.seconds = ru->ru_stime.tv_sec;
  485                 mtbi->mtbi_system_time.microseconds = ru->ru_stime.tv_usec;
  486                 mtbi->mtbi_policy = 0;
  487 
  488                 *msglen = sizeof(*rep) - sizeof(rep->rep_info) + sizeof(*mtbi);
  489                 break;
  490         }
  491 
  492         /* XXX this is supposed to be about threads, not processes... */
  493         case MACH_TASK_THREAD_TIMES_INFO: {
  494                 struct mach_task_thread_times_info *mttti;
  495                 struct rusage *ru;
  496 
  497                 count = sizeof(*mttti) / sizeof(rep->rep_info[0]);
  498                 if (req->req_count < count)
  499                         return mach_msg_error(args, ENOBUFS);
  500 
  501                 ru = &tp->p_stats->p_ru;
  502                 mttti = (struct mach_task_thread_times_info *)&rep->rep_info[0];
  503 
  504                 mttti->mttti_user_time.seconds = ru->ru_utime.tv_sec;
  505                 mttti->mttti_user_time.microseconds = ru->ru_utime.tv_usec;
  506                 mttti->mttti_system_time.seconds = ru->ru_stime.tv_sec;
  507                 mttti->mttti_system_time.microseconds = ru->ru_stime.tv_usec;
  508 
  509                 *msglen = sizeof(*rep) - sizeof(rep->rep_info) + sizeof(*mttti);
  510                 break;
  511         }
  512 
  513         /* XXX a few statistics missing here */
  514         case MACH_TASK_EVENTS_INFO: {
  515                 struct mach_task_events_info *mtei;
  516                 struct rusage *ru;
  517 
  518                 count = sizeof(*mtei) / sizeof(rep->rep_info[0]);
  519                 if (req->req_count < count)
  520                         return mach_msg_error(args, ENOBUFS);
  521 
  522                 mtei = (struct mach_task_events_info *)&rep->rep_info[0];
  523                 ru = &tp->p_stats->p_ru;
  524 
  525                 mtei->mtei_faults = ru->ru_majflt;
  526                 mtei->mtei_pageins = ru->ru_minflt;
  527                 mtei->mtei_cow_faults = 0; /* XXX */
  528                 mtei->mtei_message_sent = ru->ru_msgsnd;
  529                 mtei->mtei_message_received = ru->ru_msgrcv;
  530                 mtei->mtei_syscalls_mach = 0; /* XXX */
  531                 mtei->mtei_syscalls_unix = 0; /* XXX */
  532                 mtei->mtei_csw = 0; /* XXX */
  533 
  534                 *msglen = sizeof(*rep) - sizeof(rep->rep_info) + sizeof(*mtei);
  535                 break;
  536         }
  537 
  538         default:
  539                 uprintf("mach_task_info: unsupported flavor %d\n",
  540                     req->req_flavor);
  541                 return mach_msg_error(args, EINVAL);
  542         };
  543 
  544         mach_set_header(rep, req, *msglen);
  545 
  546         rep->rep_count = count;
  547 
  548         mach_set_trailer(rep, *msglen);
  549 
  550         return 0;
  551 }
  552 
  553 int
  554 mach_task_suspend(args)
  555         struct mach_trap_args *args;
  556 {
  557         mach_task_suspend_request_t *req = args->smsg;
  558         mach_task_suspend_reply_t *rep = args->rmsg;
  559         size_t *msglen = args->rsize;
  560         struct lwp *tl = args->tl;
  561         struct lwp *lp;
  562         struct mach_emuldata *med;
  563         struct proc *tp = tl->l_proc;
  564 
  565         med = tp->p_emuldata;
  566         med->med_suspend++; /* XXX Mach also has a per thread semaphore */
  567 
  568         LIST_FOREACH(lp, &tp->p_lwps, l_sibling) {
  569                 switch(lp->l_stat) {
  570                 case LSONPROC:
  571                 case LSRUN:
  572                 case LSSLEEP:
  573                 case LSSUSPENDED:
  574                 case LSZOMB:
  575                 case LSDEAD:
  576                         break;
  577                 default:
  578                         return mach_msg_error(args, 0);
  579                         break;
  580                 }
  581         }
  582         proc_stop(tp, 0);
  583 
  584         *msglen = sizeof(*rep);
  585         mach_set_header(rep, req, *msglen);
  586 
  587         rep->rep_retval = 0;
  588 
  589         mach_set_trailer(rep, *msglen);
  590 
  591         return 0;
  592 }
  593 
  594 int
  595 mach_task_resume(args)
  596         struct mach_trap_args *args;
  597 {
  598         mach_task_resume_request_t *req = args->smsg;
  599         mach_task_resume_reply_t *rep = args->rmsg;
  600         size_t *msglen = args->rsize;
  601         struct lwp *tl = args->tl;
  602         struct mach_emuldata *med;
  603         struct proc *tp = tl->l_proc;
  604 
  605         med = tp->p_emuldata;
  606         med->med_suspend--; /* XXX Mach also has a per thread semaphore */
  607 #if 0
  608         if (med->med_suspend > 0)
  609                 return mach_msg_error(args, 0); /* XXX error code */
  610 #endif
  611 
  612         /* XXX We should also wake up the stopped thread... */
  613 #ifdef DEBUG_MACH
  614         printf("resuming pid %d\n", tp->p_pid);
  615 #endif
  616         (void)proc_unstop(tp);
  617 
  618         *msglen = sizeof(*rep);
  619         mach_set_header(rep, req, *msglen);
  620 
  621         rep->rep_retval = 0;
  622 
  623         mach_set_trailer(rep, *msglen);
  624 
  625         return 0;
  626 }
  627 
  628 int
  629 mach_task_terminate(args)
  630         struct mach_trap_args *args;
  631 {
  632         mach_task_resume_request_t *req = args->smsg;
  633         mach_task_resume_reply_t *rep = args->rmsg;
  634         size_t *msglen = args->rsize;
  635         struct lwp *tl = args->tl;
  636         struct sys_exit_args cup;
  637         register_t retval;
  638         int error;
  639 
  640 
  641         SCARG(&cup, rval) = 0;
  642         error = sys_exit(tl, &cup, &retval);
  643 
  644         *msglen = sizeof(*rep);
  645         mach_set_header(rep, req, *msglen);
  646 
  647         rep->rep_retval = native_to_mach_errno[error];
  648 
  649         mach_set_trailer(rep, *msglen);
  650 
  651         return 0;
  652 }
  653 
  654 int
  655 mach_sys_task_for_pid(l, v, retval)
  656         struct lwp *l;
  657         void *v;
  658         register_t *retval;
  659 {
  660         struct mach_sys_task_for_pid_args /* {
  661                 syscallarg(mach_port_t) target_tport;
  662                 syscallarg(int) pid;
  663                 syscallarg(mach_port_t) *t;
  664         } */ *uap = v;
  665         struct mach_right *mr;
  666         struct mach_emuldata *med;
  667         struct proc *p = l->l_proc;
  668         struct proc *t;
  669         int error;
  670 
  671         /*
  672          * target_tport is used because the task may be on
  673          * a different host. (target_tport, pid) is unique.
  674          * We don't support multiple-host configuration
  675          * yet, so this parameter should be useless.
  676          * However, we still validate it.
  677          */
  678         if ((mr = mach_right_check(SCARG(uap, target_tport),
  679             l, MACH_PORT_TYPE_ALL_RIGHTS)) == NULL)
  680                 return EPERM;
  681 
  682         if ((t = pfind(SCARG(uap, pid))) == NULL)
  683                 return ESRCH;
  684 
  685         /* Allowed only if the UID match, if setuid, or if superuser */
  686         if ((t->p_cred->p_ruid != p->p_cred->p_ruid ||
  687                 ISSET(t->p_flag, P_SUGID)) &&
  688                     (error = suser(p->p_ucred, &p->p_acflag)) != 0)
  689                             return (error);
  690 
  691         /* This will only work on a Mach process */
  692         if ((t->p_emul != &emul_mach) &&
  693 #ifdef COMPAT_DARWIN
  694             (t->p_emul != &emul_darwin) &&
  695 #endif
  696             1)
  697                 return EINVAL;
  698 
  699         med = t->p_emuldata;
  700 
  701         if ((mr = mach_right_get(med->med_kernel, l,
  702             MACH_PORT_TYPE_SEND, 0)) == NULL)
  703                 return EINVAL;
  704 
  705         if ((error = copyout(&mr->mr_name, SCARG(uap, t),
  706             sizeof(mr->mr_name))) != 0)
  707                 return error;
  708 
  709         return 0;
  710 }
  711 

Cache object: 508c31c30e7f1ef29e2fd523c8e0aaa5


[ 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.