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/ipc/mach_debug.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 /* 
    2  * Mach Operating System
    3  * Copyright (c) 1993,1992,1991,1990 Carnegie Mellon University
    4  * All Rights Reserved.
    5  * 
    6  * Permission to use, copy, modify and distribute this software and its
    7  * documentation is hereby granted, provided that both the copyright
    8  * notice and this permission notice appear in all copies of the
    9  * software, derivative works or modified versions, and any portions
   10  * thereof, and that both notices appear in supporting documentation.
   11  * 
   12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   15  * 
   16  * Carnegie Mellon requests users of this software to return to
   17  * 
   18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   19  *  School of Computer Science
   20  *  Carnegie Mellon University
   21  *  Pittsburgh PA 15213-3890
   22  * 
   23  * any improvements or extensions that they make and grant Carnegie Mellon
   24  * the rights to redistribute these changes.
   25  */
   26 /*
   27  * HISTORY
   28  * $Log:        mach_debug.c,v $
   29  * Revision 2.10  93/11/17  17:03:38  dbg
   30  *      Added ANSI function prototypes.
   31  *      [93/09/24            dbg]
   32  * 
   33  * Revision 2.9  92/08/03  17:36:00  jfriedl
   34  *      removed silly prototypes
   35  *      [92/08/02            jfriedl]
   36  * 
   37  * Revision 2.8  92/05/21  17:12:07  jfriedl
   38  *      Added some things to quiet gcc warnings.
   39  *      [92/05/16            jfriedl]
   40  * 
   41  * Revision 2.7  92/02/23  19:52:42  elf
   42  *      Eliminate keep_wired argument from vm_map_copyin().
   43  *      [92/02/21  10:13:00  dlb]
   44  * 
   45  * Revision 2.6  92/01/14  16:44:48  rpd
   46  *      Changed host_ipc_hash_info, host_ipc_marequest_info,
   47  *      and mach_port_space_info for CountInOut.
   48  *      [92/01/14            rpd]
   49  *      Added mach_port_kernel_object.
   50  *      [91/12/14            rpd]
   51  * 
   52  * Revision 2.5  91/05/14  16:38:28  mrt
   53  *      Correcting copyright
   54  * 
   55  * Revision 2.4  91/02/05  17:24:30  mrt
   56  *      Changed to new Mach copyright
   57  *      [91/02/01  15:52:50  mrt]
   58  * 
   59  * Revision 2.3  91/01/08  15:14:55  rpd
   60  *      Changed ipc_info_bucket_t to hash_info_bucket_t.
   61  *      [91/01/02            rpd]
   62  *      Removed MACH_IPC_GENNOS.
   63  *      [90/11/08            rpd]
   64  * 
   65  * Revision 2.2  90/06/02  14:52:15  rpd
   66  *      Created for new IPC.
   67  *      [90/03/26  21:05:22  rpd]
   68  * 
   69  */
   70 /*
   71  *      File:   ipc/mach_debug.c
   72  *      Author: Rich Draves
   73  *      Date:   1989
   74  *
   75  *      Exported kernel calls.  See mach_debug/mach_debug.defs.
   76  */
   77 
   78 #include <mach_ipc_compat.h>
   79 
   80 #include <mach/kern_return.h>
   81 #include <mach/port.h>
   82 #include <mach/machine/vm_types.h>
   83 #include <mach/vm_param.h>
   84 #include <mach_debug/ipc_info.h>
   85 #include <mach_debug/hash_info.h>
   86 #include <kern/host.h>
   87 #include <kern/memory.h>
   88 #include <vm/vm_map.h>
   89 #include <vm/vm_kern.h>
   90 #include <ipc/ipc_space.h>
   91 #include <ipc/ipc_port.h>
   92 #include <ipc/ipc_hash.h>
   93 #include <ipc/ipc_marequest.h>
   94 #include <ipc/ipc_table.h>
   95 #include <ipc/ipc_right.h>
   96 
   97 
   98 
   99 /*
  100  *      Routine:        mach_port_get_srights [kernel call]
  101  *      Purpose:
  102  *              Retrieve the number of extant send rights
  103  *              that a receive right has.
  104  *      Conditions:
  105  *              Nothing locked.
  106  *      Returns:
  107  *              KERN_SUCCESS            Retrieved number of send rights.
  108  *              KERN_INVALID_TASK       The space is null.
  109  *              KERN_INVALID_TASK       The space is dead.
  110  *              KERN_INVALID_NAME       The name doesn't denote a right.
  111  *              KERN_INVALID_RIGHT      Name doesn't denote receive rights.
  112  */
  113 
  114 kern_return_t
  115 mach_port_get_srights(
  116         ipc_space_t space,
  117         mach_port_t name,
  118         mach_port_rights_t *srightsp)
  119 {
  120         ipc_port_t port;
  121         kern_return_t kr;
  122         mach_port_rights_t srights;
  123 
  124         if (space == IS_NULL)
  125                 return KERN_INVALID_TASK;
  126 
  127         kr = ipc_port_translate_receive(space, name, &port);
  128         if (kr != KERN_SUCCESS)
  129                 return kr;
  130         /* port is locked and active */
  131 
  132         srights = port->ip_srights;
  133         ip_unlock(port);
  134 
  135         *srightsp = srights;
  136         return KERN_SUCCESS;
  137 }
  138 
  139 /*
  140  *      Routine:        host_ipc_hash_info
  141  *      Purpose:
  142  *              Return information about the global reverse hash table.
  143  *      Conditions:
  144  *              Nothing locked.  Obeys CountInOut protocol.
  145  *      Returns:
  146  *              KERN_SUCCESS            Returned information.
  147  *              KERN_INVALID_HOST       The host is null.
  148  *              KERN_RESOURCE_SHORTAGE  Couldn't allocate memory.
  149  */
  150 
  151 kern_return_t
  152 host_ipc_hash_info(
  153         host_t host,
  154         hash_info_bucket_array_t *infop,
  155         mach_msg_type_number_t *countp)
  156 {
  157         vm_offset_t addr;
  158         vm_size_t size = 0; /* '=0' to shut up lint */
  159         hash_info_bucket_t *info;
  160         unsigned int potential, actual;
  161         kern_return_t kr;
  162 
  163         if (host == HOST_NULL)
  164                 return KERN_INVALID_HOST;
  165 
  166         /* start with in-line data */
  167 
  168         info = *infop;
  169         potential = *countp;
  170 
  171         for (;;) {
  172                 actual = ipc_hash_info(info, potential);
  173                 if (actual <= potential)
  174                         break;
  175 
  176                 /* allocate more memory */
  177 
  178                 if (info != *infop)
  179                         kmem_free(ipc_kernel_map, addr, size);
  180 
  181                 size = round_page(actual * sizeof *info);
  182                 kr = kmem_alloc_pageable(ipc_kernel_map, &addr, size);
  183                 if (kr != KERN_SUCCESS)
  184                         return KERN_RESOURCE_SHORTAGE;
  185 
  186                 info = (hash_info_bucket_t *) addr;
  187                 potential = size/sizeof *info;
  188         }
  189 
  190         if (info == *infop) {
  191                 /* data fit in-line; nothing to deallocate */
  192 
  193                 *countp = actual;
  194         } else if (actual == 0) {
  195                 kmem_free(ipc_kernel_map, addr, size);
  196 
  197                 *countp = 0;
  198         } else {
  199                 vm_map_copy_t copy;
  200                 vm_size_t used;
  201 
  202                 used = round_page(actual * sizeof *info);
  203 
  204                 if (used != size)
  205                         kmem_free(ipc_kernel_map, addr + used, size - used);
  206 
  207                 kr = vm_map_copyin(ipc_kernel_map, addr, used,
  208                                    TRUE, &copy);
  209                 assert(kr == KERN_SUCCESS);
  210 
  211                 *infop = (hash_info_bucket_t *) copy;
  212                 *countp = actual;
  213         }
  214 
  215         return KERN_SUCCESS;
  216 }
  217 
  218 /*
  219  *      Routine:        host_ipc_marequest_info
  220  *      Purpose:
  221  *              Return information about the marequest hash table.
  222  *      Conditions:
  223  *              Nothing locked.  Obeys CountInOut protocol.
  224  *      Returns:
  225  *              KERN_SUCCESS            Returned information.
  226  *              KERN_INVALID_HOST       The host is null.
  227  *              KERN_RESOURCE_SHORTAGE  Couldn't allocate memory.
  228  */
  229 
  230 kern_return_t
  231 host_ipc_marequest_info(
  232         host_t host,
  233         unsigned int *maxp,
  234         hash_info_bucket_array_t *infop,
  235         mach_msg_type_number_t *countp)
  236 {
  237         vm_offset_t addr;
  238         vm_size_t size = 0; /* '=0' to shut up lint */
  239         hash_info_bucket_t *info;
  240         unsigned int potential, actual;
  241         kern_return_t kr;
  242 
  243         if (host == HOST_NULL)
  244                 return KERN_INVALID_HOST;
  245 
  246         /* start with in-line data */
  247 
  248         info = *infop;
  249         potential = *countp;
  250 
  251         for (;;) {
  252                 actual = ipc_marequest_info(maxp, info, potential);
  253                 if (actual <= potential)
  254                         break;
  255 
  256                 /* allocate more memory */
  257 
  258                 if (info != *infop)
  259                         kmem_free(ipc_kernel_map, addr, size);
  260 
  261                 size = round_page(actual * sizeof *info);
  262                 kr = kmem_alloc_pageable(ipc_kernel_map, &addr, size);
  263                 if (kr != KERN_SUCCESS)
  264                         return KERN_RESOURCE_SHORTAGE;
  265 
  266                 info = (hash_info_bucket_t *) addr;
  267                 potential = size/sizeof *info;
  268         }
  269 
  270         if (info == *infop) {
  271                 /* data fit in-line; nothing to deallocate */
  272 
  273                 *countp = actual;
  274         } else if (actual == 0) {
  275                 kmem_free(ipc_kernel_map, addr, size);
  276 
  277                 *countp = 0;
  278         } else {
  279                 vm_map_copy_t copy;
  280                 vm_size_t used;
  281 
  282                 used = round_page(actual * sizeof *info);
  283 
  284                 if (used != size)
  285                         kmem_free(ipc_kernel_map, addr + used, size - used);
  286 
  287                 kr = vm_map_copyin(ipc_kernel_map, addr, used,
  288                                    TRUE, &copy);
  289                 assert(kr == KERN_SUCCESS);
  290 
  291                 *infop = (hash_info_bucket_t *) copy;
  292                 *countp = actual;
  293         }
  294 
  295         return KERN_SUCCESS;
  296 }
  297 
  298 /*
  299  *      Routine:        mach_port_space_info
  300  *      Purpose:
  301  *              Returns information about an IPC space.
  302  *      Conditions:
  303  *              Nothing locked.  Obeys CountInOut protocol.
  304  *      Returns:
  305  *              KERN_SUCCESS            Returned information.
  306  *              KERN_INVALID_TASK       The space is null.
  307  *              KERN_INVALID_TASK       The space is dead.
  308  *              KERN_RESOURCE_SHORTAGE  Couldn't allocate memory.
  309  */
  310 
  311 kern_return_t
  312 mach_port_space_info(
  313         ipc_space_t space,
  314         ipc_info_space_t *infop,
  315         ipc_info_name_array_t *tablep,
  316         mach_msg_type_number_t *tableCntp,
  317         ipc_info_tree_name_array_t *treep,
  318         mach_msg_type_number_t *treeCntp)
  319 {
  320         ipc_info_name_t *table_info;
  321         unsigned int table_potential, table_actual;
  322         vm_offset_t table_addr;
  323         vm_size_t table_size = 0; /* '=0' to shut up lint */
  324         ipc_info_tree_name_t *tree_info;
  325         unsigned int tree_potential, tree_actual;
  326         vm_offset_t tree_addr;
  327         vm_size_t tree_size = 0; /* '=0' to shut up lint */
  328         ipc_tree_entry_t tentry;
  329         ipc_entry_t table;
  330         ipc_entry_num_t tsize;
  331         mach_port_index_t index;
  332         kern_return_t kr;
  333 
  334         if (space == IS_NULL)
  335                 return KERN_INVALID_TASK;
  336 
  337         /* start with in-line memory */
  338 
  339         table_info = *tablep;
  340         table_potential = *tableCntp;
  341         tree_info = *treep;
  342         tree_potential = *treeCntp;
  343 
  344         for (;;) {
  345                 is_read_lock(space);
  346                 if (!space->is_active) {
  347                         is_read_unlock(space);
  348                         if (table_info != *tablep)
  349                                 kmem_free(ipc_kernel_map,
  350                                           table_addr, table_size);
  351                         if (tree_info != *treep)
  352                                 kmem_free(ipc_kernel_map,
  353                                           tree_addr, tree_size);
  354                         return KERN_INVALID_TASK;
  355                 }
  356 
  357                 table_actual = space->is_table_size;
  358                 tree_actual = space->is_tree_total;
  359 
  360                 if ((table_actual <= table_potential) &&
  361                     (tree_actual <= tree_potential))
  362                         break;
  363 
  364                 is_read_unlock(space);
  365 
  366                 if (table_actual > table_potential) {
  367                         if (table_info != *tablep)
  368                                 kmem_free(ipc_kernel_map,
  369                                           table_addr, table_size);
  370 
  371                         table_size = round_page(table_actual *
  372                                                 sizeof *table_info);
  373                         kr = kmem_alloc(ipc_kernel_map,
  374                                         &table_addr, table_size);
  375                         if (kr != KERN_SUCCESS) {
  376                                 if (tree_info != *treep)
  377                                         kmem_free(ipc_kernel_map,
  378                                                   tree_addr, tree_size);
  379 
  380                                 return KERN_RESOURCE_SHORTAGE;
  381                         }
  382 
  383                         table_info = (ipc_info_name_t *) table_addr;
  384                         table_potential = table_size/sizeof *table_info;
  385                 }
  386 
  387                 if (tree_actual > tree_potential) {
  388                         if (tree_info != *treep)
  389                                 kmem_free(ipc_kernel_map,
  390                                           tree_addr, tree_size);
  391 
  392                         tree_size = round_page(tree_actual *
  393                                                sizeof *tree_info);
  394                         kr = kmem_alloc(ipc_kernel_map,
  395                                         &tree_addr, tree_size);
  396                         if (kr != KERN_SUCCESS) {
  397                                 if (table_info != *tablep)
  398                                         kmem_free(ipc_kernel_map,
  399                                                   table_addr, table_size);
  400 
  401                                 return KERN_RESOURCE_SHORTAGE;
  402                         }
  403 
  404                         tree_info = (ipc_info_tree_name_t *) tree_addr;
  405                         tree_potential = tree_size/sizeof *tree_info;
  406                 }
  407         }
  408         /* space is read-locked and active; we have enough wired memory */
  409 
  410         infop->iis_genno_mask = MACH_PORT_NGEN(MACH_PORT_DEAD);
  411         infop->iis_table_size = space->is_table_size;
  412         infop->iis_table_next = space->is_table_next->its_size;
  413         infop->iis_tree_size = space->is_tree_total;
  414         infop->iis_tree_small = space->is_tree_small;
  415         infop->iis_tree_hash = space->is_tree_hash;
  416 
  417         table = space->is_table;
  418         tsize = space->is_table_size;
  419 
  420         for (index = 0; index < tsize; index++) {
  421                 ipc_info_name_t *iin = &table_info[index];
  422                 ipc_entry_t entry = &table[index];
  423                 ipc_entry_bits_t bits = entry->ie_bits;
  424 
  425                 iin->iin_name = MACH_PORT_MAKEB(index, bits);
  426                 iin->iin_collision = (bits & IE_BITS_COLLISION) ? TRUE : FALSE;
  427 #if     MACH_IPC_COMPAT
  428                 iin->iin_compat = (bits & IE_BITS_COMPAT) ? TRUE : FALSE;
  429 #else   /* MACH_IPC_COMPAT */
  430                 iin->iin_compat = FALSE;
  431 #endif  /* MACH_IPC_COMPAT */
  432                 iin->iin_marequest = (bits & IE_BITS_MAREQUEST) ? TRUE : FALSE;
  433                 iin->iin_type = IE_BITS_TYPE(bits);
  434                 iin->iin_urefs = IE_BITS_UREFS(bits);
  435                 iin->iin_object = (vm_offset_t) entry->ie_object;
  436                 iin->iin_next = entry->ie_next;
  437                 iin->iin_hash = entry->ie_index;
  438         }
  439 
  440         for (tentry = ipc_splay_traverse_start(&space->is_tree), index = 0;
  441              tentry != ITE_NULL;
  442              tentry = ipc_splay_traverse_next(&space->is_tree, FALSE)) {
  443                 ipc_info_tree_name_t *iitn = &tree_info[index++];
  444                 ipc_info_name_t *iin = &iitn->iitn_name;
  445                 ipc_entry_t entry = &tentry->ite_entry;
  446                 ipc_entry_bits_t bits = entry->ie_bits;
  447 
  448                 assert(IE_BITS_TYPE(bits) != MACH_PORT_TYPE_NONE);
  449 
  450                 iin->iin_name = tentry->ite_name;
  451                 iin->iin_collision = (bits & IE_BITS_COLLISION) ? TRUE : FALSE;
  452 #if     MACH_IPC_COMPAT
  453                 iin->iin_compat = (bits & IE_BITS_COMPAT) ? TRUE : FALSE;
  454 #else   /* MACH_IPC_COMPAT */
  455                 iin->iin_compat = FALSE;
  456 #endif  /* MACH_IPC_COMPAT */
  457                 iin->iin_marequest = (bits & IE_BITS_MAREQUEST) ? TRUE : FALSE;
  458                 iin->iin_type = IE_BITS_TYPE(bits);
  459                 iin->iin_urefs = IE_BITS_UREFS(bits);
  460                 iin->iin_object = (vm_offset_t) entry->ie_object;
  461                 iin->iin_next = entry->ie_next;
  462                 iin->iin_hash = entry->ie_index;
  463 
  464                 if (tentry->ite_lchild == ITE_NULL)
  465                         iitn->iitn_lchild = MACH_PORT_NULL;
  466                 else
  467                         iitn->iitn_lchild = tentry->ite_lchild->ite_name;
  468 
  469                 if (tentry->ite_rchild == ITE_NULL)
  470                         iitn->iitn_rchild = MACH_PORT_NULL;
  471                 else
  472                         iitn->iitn_rchild = tentry->ite_rchild->ite_name;
  473 
  474         }
  475         ipc_splay_traverse_finish(&space->is_tree);
  476         is_read_unlock(space);
  477 
  478         if (table_info == *tablep) {
  479                 /* data fit in-line; nothing to deallocate */
  480 
  481                 *tableCntp = table_actual;
  482         } else if (table_actual == 0) {
  483                 kmem_free(ipc_kernel_map, table_addr, table_size);
  484 
  485                 *tableCntp = 0;
  486         } else {
  487                 vm_size_t size_used, rsize_used;
  488                 vm_map_copy_t copy;
  489 
  490                 /* kmem_alloc doesn't zero memory */
  491 
  492                 size_used = table_actual * sizeof *table_info;
  493                 rsize_used = round_page(size_used);
  494 
  495                 if (rsize_used != table_size)
  496                         kmem_free(ipc_kernel_map,
  497                                   table_addr + rsize_used,
  498                                   table_size - rsize_used);
  499 
  500                 if (size_used != rsize_used)
  501                         bzero((void *) (table_addr + size_used),
  502                               rsize_used - size_used);
  503 
  504                 kr = vm_map_copyin(ipc_kernel_map, table_addr, rsize_used,
  505                                    TRUE, &copy);
  506 
  507                 assert(kr == KERN_SUCCESS);
  508 
  509                 *tablep = (ipc_info_name_t *) copy;
  510                 *tableCntp = table_actual;
  511         }
  512 
  513         if (tree_info == *treep) {
  514                 /* data fit in-line; nothing to deallocate */
  515 
  516                 *treeCntp = tree_actual;
  517         } else if (tree_actual == 0) {
  518                 kmem_free(ipc_kernel_map, tree_addr, tree_size);
  519 
  520                 *treeCntp = 0;
  521         } else {
  522                 vm_size_t size_used, rsize_used;
  523                 vm_map_copy_t copy;
  524 
  525                 /* kmem_alloc doesn't zero memory */
  526 
  527                 size_used = tree_actual * sizeof *tree_info;
  528                 rsize_used = round_page(size_used);
  529 
  530                 if (rsize_used != tree_size)
  531                         kmem_free(ipc_kernel_map,
  532                                   tree_addr + rsize_used,
  533                                   tree_size - rsize_used);
  534 
  535                 if (size_used != rsize_used)
  536                         bzero((char *) (tree_addr + size_used),
  537                               rsize_used - size_used);
  538 
  539                 kr = vm_map_copyin(ipc_kernel_map, tree_addr, rsize_used,
  540                                    TRUE, &copy);
  541 
  542                 assert(kr == KERN_SUCCESS);
  543 
  544                 *treep = (ipc_info_tree_name_t *) copy;
  545                 *treeCntp = tree_actual;
  546         }
  547 
  548         return KERN_SUCCESS;
  549 }
  550 
  551 /*
  552  *      Routine:        mach_port_dnrequest_info
  553  *      Purpose:
  554  *              Returns information about the dead-name requests
  555  *              registered with the named receive right.
  556  *      Conditions:
  557  *              Nothing locked.
  558  *      Returns:
  559  *              KERN_SUCCESS            Retrieved information.
  560  *              KERN_INVALID_TASK       The space is null.
  561  *              KERN_INVALID_TASK       The space is dead.
  562  *              KERN_INVALID_NAME       The name doesn't denote a right.
  563  *              KERN_INVALID_RIGHT      Name doesn't denote receive rights.
  564  */
  565 
  566 kern_return_t
  567 mach_port_dnrequest_info(
  568         ipc_space_t space,
  569         mach_port_t name,
  570         unsigned int *totalp,
  571         unsigned int *usedp)
  572 {
  573         unsigned int total, used;
  574         ipc_port_t port;
  575         kern_return_t kr;
  576 
  577         if (space == IS_NULL)
  578                 return KERN_INVALID_TASK;
  579 
  580         kr = ipc_port_translate_receive(space, name, &port);
  581         if (kr != KERN_SUCCESS)
  582                 return kr;
  583         /* port is locked and active */
  584 
  585         if (port->ip_dnrequests == IPR_NULL) {
  586                 total = 0;
  587                 used = 0;
  588         } else {
  589                 ipc_port_request_t dnrequests = port->ip_dnrequests;
  590                 ipc_port_request_index_t index;
  591 
  592                 total = dnrequests->ipr_size->its_size;
  593 
  594                 for (index = 1, used = 0;
  595                      index < total; index++) {
  596                         ipc_port_request_t ipr = &dnrequests[index];
  597 
  598                         if (ipr->ipr_name != MACH_PORT_NULL)
  599                                 used++;
  600                 }
  601         }
  602         ip_unlock(port);
  603 
  604         *totalp = total;
  605         *usedp = used;
  606         return KERN_SUCCESS;
  607 }
  608 
  609 /*
  610  *      Routine:        mach_port_kernel_object [kernel call]
  611  *      Purpose:
  612  *              Retrieve the type and address of the kernel object
  613  *              represented by a send or receive right.
  614  *      Conditions:
  615  *              Nothing locked.
  616  *      Returns:
  617  *              KERN_SUCCESS            Retrieved kernel object info.
  618  *              KERN_INVALID_TASK       The space is null.
  619  *              KERN_INVALID_TASK       The space is dead.
  620  *              KERN_INVALID_NAME       The name doesn't denote a right.
  621  *              KERN_INVALID_RIGHT      Name doesn't denote
  622  *                                      send or receive rights.
  623  */
  624 
  625 kern_return_t
  626 mach_port_kernel_object(
  627         ipc_space_t space,
  628         mach_port_t name,
  629         unsigned int *typep,
  630         vm_offset_t *addrp)
  631 {
  632         ipc_entry_t entry;
  633         ipc_port_t port;
  634         kern_return_t kr;
  635 
  636         kr = ipc_right_lookup_read(space, name, &entry);
  637         if (kr != KERN_SUCCESS)
  638                 return kr;
  639         /* space is read-locked and active */
  640 
  641         if ((entry->ie_bits & MACH_PORT_TYPE_SEND_RECEIVE) == 0) {
  642                 is_read_unlock(space);
  643                 return KERN_INVALID_RIGHT;
  644         }
  645 
  646         port = (ipc_port_t) entry->ie_object;
  647         assert(port != IP_NULL);
  648 
  649         ip_lock(port);
  650         is_read_unlock(space);
  651 
  652         if (!ip_active(port)) {
  653                 ip_unlock(port);
  654                 return KERN_INVALID_RIGHT;
  655         }
  656 
  657         *typep = (unsigned int) ip_kotype(port);
  658         *addrp = (vm_offset_t) port->ip_kobject;
  659         ip_unlock(port);
  660         return KERN_SUCCESS;
  661 }

Cache object: c5c7cb0d4c50fa483d515d9d9c8211bb


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