Annotation of kernel/ipc/mach_debug.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: 
                     25: /*
                     26:  * Copyright (c) 1995, 1994, 1993, 1992, 1991, 1990  
                     27:  * Open Software Foundation, Inc. 
                     28:  *  
                     29:  * Permission to use, copy, modify, and distribute this software and 
                     30:  * its documentation for any purpose and without fee is hereby granted, 
                     31:  * provided that the above copyright notice appears in all copies and 
                     32:  * that both the copyright notice and this permission notice appear in 
                     33:  * supporting documentation, and that the name of ("OSF") or Open Software 
                     34:  * Foundation not be used in advertising or publicity pertaining to 
                     35:  * distribution of the software without specific, written prior permission. 
                     36:  *  
                     37:  * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 
                     38:  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
                     39:  * FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL OSF BE LIABLE FOR ANY 
                     40:  * SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 
                     41:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 
                     42:  * ACTION OF CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING 
                     43:  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE 
                     44:  */
                     45: /*
                     46:  * OSF Research Institute MK6.1 (unencumbered) 1/31/1995
                     47:  */
                     48: /* 
                     49:  * Mach Operating System
                     50:  * Copyright (c) 1991,1990 Carnegie Mellon University
                     51:  * All Rights Reserved.
                     52:  * 
                     53:  * Permission to use, copy, modify and distribute this software and its
                     54:  * documentation is hereby granted, provided that both the copyright
                     55:  * notice and this permission notice appear in all copies of the
                     56:  * software, derivative works or modified versions, and any portions
                     57:  * thereof, and that both notices appear in supporting documentation.
                     58:  * 
                     59:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     60:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     61:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     62:  * 
                     63:  * Carnegie Mellon requests users of this software to return to
                     64:  * 
                     65:  *  Software Distribution Coordinator  or  [email protected]
                     66:  *  School of Computer Science
                     67:  *  Carnegie Mellon University
                     68:  *  Pittsburgh PA 15213-3890
                     69:  * 
                     70:  * any improvements or extensions that they make and grant Carnegie Mellon
                     71:  * the rights to redistribute these changes.
                     72:  */
                     73: /*
                     74:  *     File:   ipc/mach_debug.c
                     75:  *     Author: Rich Draves
                     76:  *     Date:   1989
                     77:  *
                     78:  *     Exported kernel calls.  See mach_debug/mach_debug.defs.
                     79:  */
                     80: 
                     81: #import <mach/features.h>
                     82: 
                     83: #include <mach/kern_return.h>
                     84: #include <mach/port.h>
                     85: #include <mach/machine/vm_types.h>
                     86: #include <mach/vm_param.h>
                     87: #include <mach_debug/ipc_info.h>
                     88: #include <mach_debug/hash_info.h>
                     89: #include <kern/host.h>
                     90: #include <vm/vm_map.h>
                     91: #include <vm/vm_kern.h>
                     92: #include <ipc/ipc_space.h>
                     93: #include <ipc/ipc_port.h>
                     94: #include <ipc/ipc_hash.h>
                     95: #include <ipc/ipc_marequest.h>
                     96: #include <ipc/ipc_table.h>
                     97: #include <ipc/ipc_right.h>
                     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:        unsigned int                    *countp)
                    156: {
                    157:        vm_offset_t addr;
                    158:        vm_size_t size;
                    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: #if    MACH_OLD_VM_COPY
                    200:                vm_offset_t copy;
                    201: #else  /* MACH_OLD_VM_COPY */
                    202:                vm_map_copy_t copy;
                    203: #endif /* MACH_OLD_VM_COPY */
                    204:                vm_size_t used;
                    205: 
                    206:                used = round_page(actual * sizeof *info);
                    207: 
                    208:                if (used != size)
                    209:                        kmem_free(ipc_kernel_map, addr + used, size - used);
                    210: 
                    211: #if    MACH_OLD_VM_COPY
                    212:                kr = vm_move(
                    213:                        ipc_kernel_map, addr,
                    214:                        ipc_soft_map, used,
                    215:                        TRUE, &copy);
                    216:                assert(kr == KERN_SUCCESS);
                    217: #else  /* MACH_OLD_VM_COPY */
                    218:                kr = vm_map_copyin(ipc_kernel_map, addr, used,
                    219:                                   TRUE, &copy);
                    220:                assert(kr == KERN_SUCCESS);
                    221: #endif /* MACH_OLD_VM_COPY */
                    222: 
                    223:                *infop = (hash_info_bucket_t *) copy;
                    224:                *countp = actual;
                    225:        }
                    226: 
                    227:        return KERN_SUCCESS;
                    228: }
                    229: 
                    230: /*
                    231:  *     Routine:        host_ipc_marequest_info
                    232:  *     Purpose:
                    233:  *             Return information about the marequest hash table.
                    234:  *     Conditions:
                    235:  *             Nothing locked.  Obeys CountInOut protocol.
                    236:  *     Returns:
                    237:  *             KERN_SUCCESS            Returned information.
                    238:  *             KERN_INVALID_HOST       The host is null.
                    239:  *             KERN_RESOURCE_SHORTAGE  Couldn't allocate memory.
                    240:  */
                    241: 
                    242: kern_return_t
                    243: host_ipc_marequest_info(
                    244:        host_t                          host,
                    245:        unsigned int                    *maxp,
                    246:        hash_info_bucket_array_t        *infop,
                    247:        unsigned int                    *countp)
                    248: {
                    249:        vm_offset_t addr;
                    250:        vm_size_t size;
                    251:        hash_info_bucket_t *info;
                    252:        unsigned int potential, actual;
                    253:        kern_return_t kr;
                    254: 
                    255:        if (host == HOST_NULL)
                    256:                return KERN_INVALID_HOST;
                    257: 
                    258:        /* start with in-line data */
                    259: 
                    260:        info = *infop;
                    261:        potential = *countp;
                    262: 
                    263:        for (;;) {
                    264:                actual = ipc_marequest_info(maxp, info, potential);
                    265:                if (actual <= potential)
                    266:                        break;
                    267: 
                    268:                /* allocate more memory */
                    269: 
                    270:                if (info != *infop)
                    271:                        kmem_free(ipc_kernel_map, addr, size);
                    272: 
                    273:                size = round_page(actual * sizeof *info);
                    274:                kr = kmem_alloc_pageable(ipc_kernel_map, &addr, size);
                    275:                if (kr != KERN_SUCCESS)
                    276:                        return KERN_RESOURCE_SHORTAGE;
                    277: 
                    278:                info = (hash_info_bucket_t *) addr;
                    279:                potential = size/sizeof *info;
                    280:        }
                    281: 
                    282:        if (info == *infop) {
                    283:                /* data fit in-line; nothing to deallocate */
                    284: 
                    285:                *countp = actual;
                    286:        } else if (actual == 0) {
                    287:                kmem_free(ipc_kernel_map, addr, size);
                    288: 
                    289:                *countp = 0;
                    290:        } else {
                    291: #if    MACH_OLD_VM_COPY
                    292:                vm_offset_t copy;
                    293: #else  /* MACH_OLD_VM_COPY */
                    294:                vm_map_copy_t copy;
                    295: #endif /* MACH_OLD_VM_COPY */
                    296:                vm_size_t used;
                    297: 
                    298:                used = round_page(actual * sizeof *info);
                    299: 
                    300:                if (used != size)
                    301:                        kmem_free(ipc_kernel_map, addr + used, size - used);
                    302: 
                    303: #if    MACH_OLD_VM_COPY
                    304:                kr = vm_move(
                    305:                        ipc_kernel_map, addr,
                    306:                        ipc_soft_map, used,
                    307:                        TRUE, &copy);
                    308:                assert(kr == KERN_SUCCESS);
                    309: #else  /* MACH_OLD_VM_COPY */
                    310:                kr = vm_map_copyin(ipc_kernel_map, addr, used,
                    311:                                   TRUE, &copy);
                    312:                assert(kr == KERN_SUCCESS);
                    313: #endif /* MACH_OLD_VM_COPY */
                    314: 
                    315:                *infop = (hash_info_bucket_t *) copy;
                    316:                *countp = actual;
                    317:        }
                    318: 
                    319:        return KERN_SUCCESS;
                    320: }
                    321: 
                    322: /*
                    323:  *     Routine:        mach_port_space_info
                    324:  *     Purpose:
                    325:  *             Returns information about an IPC space.
                    326:  *     Conditions:
                    327:  *             Nothing locked.  Obeys CountInOut protocol.
                    328:  *     Returns:
                    329:  *             KERN_SUCCESS            Returned information.
                    330:  *             KERN_INVALID_TASK       The space is null.
                    331:  *             KERN_INVALID_TASK       The space is dead.
                    332:  *             KERN_RESOURCE_SHORTAGE  Couldn't allocate memory.
                    333:  */
                    334: 
                    335: kern_return_t
                    336: mach_port_space_info(
                    337:        ipc_space_t                     space,
                    338:        ipc_info_space_t                *infop,
                    339:        ipc_info_name_array_t           *tablep,
                    340:        unsigned int                    *tableCntp,
                    341:        ipc_info_tree_name_array_t      *treep,
                    342:        unsigned int                    *treeCntp)
                    343: {
                    344:        ipc_info_name_t *table_info;
                    345:        unsigned int table_potential, table_actual;
                    346:        vm_offset_t table_addr;
                    347:        vm_size_t table_size;
                    348:        ipc_info_tree_name_t *tree_info;
                    349:        unsigned int tree_potential, tree_actual;
                    350:        vm_offset_t tree_addr;
                    351:        vm_size_t tree_size;
                    352:        ipc_tree_entry_t tentry;
                    353:        ipc_entry_t table;
                    354:        ipc_entry_num_t tsize;
                    355:        mach_port_index_t index;
                    356:        kern_return_t kr;
                    357: 
                    358:        if (space == IS_NULL)
                    359:                return KERN_INVALID_TASK;
                    360: 
                    361:        /* start with in-line memory */
                    362: 
                    363:        table_info = *tablep;
                    364:        table_potential = *tableCntp;
                    365:        tree_info = *treep;
                    366:        tree_potential = *treeCntp;
                    367: 
                    368:        for (;;) {
                    369:                is_read_lock(space);
                    370:                if (!space->is_active) {
                    371:                        is_read_unlock(space);
                    372:                        if (table_info != *tablep)
                    373:                                kmem_free(ipc_kernel_map,
                    374:                                          table_addr, table_size);
                    375:                        if (tree_info != *treep)
                    376:                                kmem_free(ipc_kernel_map,
                    377:                                          tree_addr, tree_size);
                    378:                        return KERN_INVALID_TASK;
                    379:                }
                    380: 
                    381:                table_actual = space->is_table_size;
                    382:                tree_actual = space->is_tree_total;
                    383: 
                    384:                if ((table_actual <= table_potential) &&
                    385:                    (tree_actual <= tree_potential))
                    386:                        break;
                    387: 
                    388:                is_read_unlock(space);
                    389: 
                    390:                if (table_actual > table_potential) {
                    391:                        if (table_info != *tablep)
                    392:                                kmem_free(ipc_kernel_map,
                    393:                                          table_addr, table_size);
                    394: 
                    395:                        table_size = round_page(table_actual *
                    396:                                                sizeof *table_info);
                    397:                        kr = kmem_alloc(ipc_kernel_map,
                    398:                                        &table_addr, table_size);
                    399:                        if (kr != KERN_SUCCESS) {
                    400:                                if (tree_info != *treep)
                    401:                                        kmem_free(ipc_kernel_map,
                    402:                                                  tree_addr, tree_size);
                    403: 
                    404:                                return KERN_RESOURCE_SHORTAGE;
                    405:                        }
                    406: 
                    407:                        table_info = (ipc_info_name_t *) table_addr;
                    408:                        table_potential = table_size/sizeof *table_info;
                    409:                }
                    410: 
                    411:                if (tree_actual > tree_potential) {
                    412:                        if (tree_info != *treep)
                    413:                                kmem_free(ipc_kernel_map,
                    414:                                          tree_addr, tree_size);
                    415: 
                    416:                        tree_size = round_page(tree_actual *
                    417:                                               sizeof *tree_info);
                    418:                        kr = kmem_alloc(ipc_kernel_map,
                    419:                                        &tree_addr, tree_size);
                    420:                        if (kr != KERN_SUCCESS) {
                    421:                                if (table_info != *tablep)
                    422:                                        kmem_free(ipc_kernel_map,
                    423:                                                  table_addr, table_size);
                    424: 
                    425:                                return KERN_RESOURCE_SHORTAGE;
                    426:                        }
                    427: 
                    428:                        tree_info = (ipc_info_tree_name_t *) tree_addr;
                    429:                        tree_potential = tree_size/sizeof *tree_info;
                    430:                }
                    431:        }
                    432:        /* space is read-locked and active; we have enough wired memory */
                    433: 
                    434:        infop->iis_genno_mask = MACH_PORT_NGEN(MACH_PORT_DEAD);
                    435:        infop->iis_table_size = space->is_table_size;
                    436:        infop->iis_table_next = space->is_table_next->its_size;
                    437:        infop->iis_tree_size = space->is_tree_total;
                    438:        infop->iis_tree_small = space->is_tree_small;
                    439:        infop->iis_tree_hash = space->is_tree_hash;
                    440: 
                    441:        table = space->is_table;
                    442:        tsize = space->is_table_size;
                    443: 
                    444:        for (index = 0; index < tsize; index++) {
                    445:                ipc_info_name_t *iin = &table_info[index];
                    446:                ipc_entry_t entry = &table[index];
                    447:                ipc_entry_bits_t bits = entry->ie_bits;
                    448: 
                    449:                iin->iin_name = MACH_PORT_MAKEB(index, bits);
                    450:                iin->iin_collision = (bits & IE_BITS_COLLISION) ? TRUE : FALSE;
                    451: #if    MACH_IPC_COMPAT
                    452:                iin->iin_compat = (bits & IE_BITS_COMPAT) ? TRUE : FALSE;
                    453: #else  /* MACH_IPC_COMPAT */
                    454:                iin->iin_compat = FALSE;
                    455: #endif /* MACH_IPC_COMPAT */
                    456:                iin->iin_marequest = (bits & IE_BITS_MAREQUEST) ? TRUE : FALSE;
                    457:                iin->iin_type = IE_BITS_TYPE(bits);
                    458:                iin->iin_urefs = IE_BITS_UREFS(bits);
                    459:                iin->iin_object = (vm_offset_t) entry->ie_object;
                    460:                iin->iin_next = entry->ie_next;
                    461:                iin->iin_hash = entry->ie_index;
                    462:        }
                    463: 
                    464:        for (tentry = ipc_splay_traverse_start(&space->is_tree), index = 0;
                    465:             tentry != ITE_NULL;
                    466:             tentry = ipc_splay_traverse_next(&space->is_tree, FALSE)) {
                    467:                ipc_info_tree_name_t *iitn = &tree_info[index++];
                    468:                ipc_info_name_t *iin = &iitn->iitn_name;
                    469:                ipc_entry_t entry = &tentry->ite_entry;
                    470:                ipc_entry_bits_t bits = entry->ie_bits;
                    471: 
                    472:                assert(IE_BITS_TYPE(bits) != MACH_PORT_TYPE_NONE);
                    473: 
                    474:                iin->iin_name = tentry->ite_name;
                    475:                iin->iin_collision = (bits & IE_BITS_COLLISION) ? TRUE : FALSE;
                    476: #if    MACH_IPC_COMPAT
                    477:                iin->iin_compat = (bits & IE_BITS_COMPAT) ? TRUE : FALSE;
                    478: #else  /* MACH_IPC_COMPAT */
                    479:                iin->iin_compat = FALSE;
                    480: #endif /* MACH_IPC_COMPAT */
                    481:                iin->iin_marequest = (bits & IE_BITS_MAREQUEST) ? TRUE : FALSE;
                    482:                iin->iin_type = IE_BITS_TYPE(bits);
                    483:                iin->iin_urefs = IE_BITS_UREFS(bits);
                    484:                iin->iin_object = (vm_offset_t) entry->ie_object;
                    485:                iin->iin_next = entry->ie_next;
                    486:                iin->iin_hash = entry->ie_index;
                    487: 
                    488:                if (tentry->ite_lchild == ITE_NULL)
                    489:                        iitn->iitn_lchild = MACH_PORT_NULL;
                    490:                else
                    491:                        iitn->iitn_lchild = tentry->ite_lchild->ite_name;
                    492: 
                    493:                if (tentry->ite_rchild == ITE_NULL)
                    494:                        iitn->iitn_rchild = MACH_PORT_NULL;
                    495:                else
                    496:                        iitn->iitn_rchild = tentry->ite_rchild->ite_name;
                    497: 
                    498:        }
                    499:        ipc_splay_traverse_finish(&space->is_tree);
                    500:        is_read_unlock(space);
                    501: 
                    502:        if (table_info == *tablep) {
                    503:                /* data fit in-line; nothing to deallocate */
                    504: 
                    505:                *tableCntp = table_actual;
                    506:        } else if (table_actual == 0) {
                    507:                kmem_free(ipc_kernel_map, table_addr, table_size);
                    508: 
                    509:                *tableCntp = 0;
                    510:        } else {
                    511:                vm_size_t size_used, rsize_used;
                    512: #if    MACH_OLD_VM_COPY
                    513:                vm_offset_t copy;
                    514: #else  /* MACH_OLD_VM_COPY */
                    515:                vm_map_copy_t copy;
                    516: #endif /* MACH_OLD_VM_COPY */
                    517: 
                    518:                /* kmem_alloc doesn't zero memory */
                    519: 
                    520:                size_used = table_actual * sizeof *table_info;
                    521:                rsize_used = round_page(size_used);
                    522: 
                    523:                if (rsize_used != table_size)
                    524:                        kmem_free(ipc_kernel_map,
                    525:                                  table_addr + rsize_used,
                    526:                                  table_size - rsize_used);
                    527: 
                    528:                if (size_used != rsize_used)
                    529:                        bzero((char *) (table_addr + size_used),
                    530:                              rsize_used - size_used);
                    531: 
                    532: #if    MACH_OLD_VM_COPY
                    533:                kr = vm_move(
                    534:                        ipc_kernel_map, table_addr,
                    535:                        ipc_soft_map, rsize_used,
                    536:                        TRUE, &copy);
                    537:                assert(kr == KERN_SUCCESS);
                    538: #else  /* MACH_OLD_VM_COPY */
                    539:                kr = vm_map_unwire(ipc_kernel_map, table_addr,
                    540:                                   table_addr + rsize_used, FALSE);
                    541:                assert(kr == KERN_SUCCESS);
                    542: 
                    543:                kr = vm_map_copyin(ipc_kernel_map, table_addr, rsize_used,
                    544:                                   TRUE, &copy);
                    545:                assert(kr == KERN_SUCCESS);
                    546: #endif /* MACH_OLD_VM_COPY */
                    547: 
                    548:                *tablep = (ipc_info_name_t *) copy;
                    549:                *tableCntp = table_actual;
                    550:        }
                    551: 
                    552:        if (tree_info == *treep) {
                    553:                /* data fit in-line; nothing to deallocate */
                    554: 
                    555:                *treeCntp = tree_actual;
                    556:        } else if (tree_actual == 0) {
                    557:                kmem_free(ipc_kernel_map, tree_addr, tree_size);
                    558: 
                    559:                *treeCntp = 0;
                    560:        } else {
                    561:                vm_size_t size_used, rsize_used;
                    562: #if    MACH_OLD_VM_COPY
                    563:                vm_offset_t copy;
                    564: #else  /* MACH_OLD_VM_COPY */
                    565:                vm_map_copy_t copy;
                    566: #endif /* MACH_OLD_VM_COPY */
                    567: 
                    568:                /* kmem_alloc doesn't zero memory */
                    569: 
                    570:                size_used = tree_actual * sizeof *tree_info;
                    571:                rsize_used = round_page(size_used);
                    572: 
                    573:                if (rsize_used != tree_size)
                    574:                        kmem_free(ipc_kernel_map,
                    575:                                  tree_addr + rsize_used,
                    576:                                  tree_size - rsize_used);
                    577: 
                    578:                if (size_used != rsize_used)
                    579:                        bzero((char *) (tree_addr + size_used),
                    580:                              rsize_used - size_used);
                    581: 
                    582: #if    MACH_OLD_VM_COPY
                    583:                kr = vm_move(
                    584:                        ipc_kernel_map, tree_addr,
                    585:                        ipc_soft_map, rsize_used,
                    586:                        TRUE, &copy);
                    587:                assert(kr == KERN_SUCCESS);
                    588: #else  /* MACH_OLD_VM_COPY */
                    589:                kr = vm_map_unwire(ipc_kernel_map, tree_addr,
                    590:                                   tree_addr + rsize_used, FALSE);
                    591:                assert(kr == KERN_SUCCESS);
                    592: 
                    593:                kr = vm_map_copyin(ipc_kernel_map, tree_addr, rsize_used,
                    594:                                   TRUE, &copy);
                    595:                assert(kr == KERN_SUCCESS);
                    596: #endif /* MACH_OLD_VM_COPY */
                    597: 
                    598:                *treep = (ipc_info_tree_name_t *) copy;
                    599:                *treeCntp = tree_actual;
                    600:        }
                    601: 
                    602:        return KERN_SUCCESS;
                    603: }
                    604: 
                    605: /*
                    606:  *     Routine:        mach_port_dnrequest_info
                    607:  *     Purpose:
                    608:  *             Returns information about the dead-name requests
                    609:  *             registered with the named receive right.
                    610:  *     Conditions:
                    611:  *             Nothing locked.
                    612:  *     Returns:
                    613:  *             KERN_SUCCESS            Retrieved information.
                    614:  *             KERN_INVALID_TASK       The space is null.
                    615:  *             KERN_INVALID_TASK       The space is dead.
                    616:  *             KERN_INVALID_NAME       The name doesn't denote a right.
                    617:  *             KERN_INVALID_RIGHT      Name doesn't denote receive rights.
                    618:  */
                    619: 
                    620: kern_return_t
                    621: mach_port_dnrequest_info(
                    622:        ipc_space_t     space,
                    623:        mach_port_t     name,
                    624:        unsigned int    *totalp,
                    625:        unsigned int    *usedp)
                    626: {
                    627:        unsigned int total, used;
                    628:        ipc_port_t port;
                    629:        kern_return_t kr;
                    630: 
                    631:        if (space == IS_NULL)
                    632:                return KERN_INVALID_TASK;
                    633: 
                    634:        kr = ipc_port_translate_receive(space, name, &port);
                    635:        if (kr != KERN_SUCCESS)
                    636:                return kr;
                    637:        /* port is locked and active */
                    638: 
                    639:        if (port->ip_dnrequests == IPR_NULL) {
                    640:                total = 0;
                    641:                used = 0;
                    642:        } else {
                    643:                ipc_port_request_t dnrequests = port->ip_dnrequests;
                    644:                ipc_port_request_index_t index;
                    645: 
                    646:                total = dnrequests->ipr_size->its_size;
                    647: 
                    648:                for (index = 1, used = 0;
                    649:                     index < total; index++) {
                    650:                        ipc_port_request_t ipr = &dnrequests[index];
                    651: 
                    652:                        if (ipr->ipr_name != MACH_PORT_NULL)
                    653:                                used++;
                    654:                }
                    655:        }
                    656:        ip_unlock(port);
                    657: 
                    658:        *totalp = total;
                    659:        *usedp = used;
                    660:        return KERN_SUCCESS;
                    661: }
                    662: 
                    663: /*
                    664:  *     Routine:        mach_port_kernel_object [kernel call]
                    665:  *     Purpose:
                    666:  *             Retrieve the type and address of the kernel object
                    667:  *             represented by a send or receive right.
                    668:  *     Conditions:
                    669:  *             Nothing locked.
                    670:  *     Returns:
                    671:  *             KERN_SUCCESS            Retrieved kernel object info.
                    672:  *             KERN_INVALID_TASK       The space is null.
                    673:  *             KERN_INVALID_TASK       The space is dead.
                    674:  *             KERN_INVALID_NAME       The name doesn't denote a right.
                    675:  *             KERN_INVALID_RIGHT      Name doesn't denote
                    676:  *                                     send or receive rights.
                    677:  */
                    678: 
                    679: kern_return_t
                    680: mach_port_kernel_object(
                    681:        ipc_space_t     space,
                    682:        mach_port_t     name,
                    683:        unsigned int    *typep,
                    684:        vm_offset_t     *addrp)
                    685: {
                    686:        ipc_entry_t entry;
                    687:        ipc_port_t port;
                    688:        kern_return_t kr;
                    689: 
                    690:        kr = ipc_right_lookup_read(space, name, &entry);
                    691:        if (kr != KERN_SUCCESS)
                    692:                return kr;
                    693:        /* space is read-locked and active */
                    694: 
                    695:        if ((entry->ie_bits & MACH_PORT_TYPE_SEND_RECEIVE) == 0) {
                    696:                is_read_unlock(space);
                    697:                return KERN_INVALID_RIGHT;
                    698:        }
                    699: 
                    700:        port = (ipc_port_t) entry->ie_object;
                    701:        assert(port != IP_NULL);
                    702: 
                    703:        ip_lock(port);
                    704:        is_read_unlock(space);
                    705: 
                    706:        if (!ip_active(port)) {
                    707:                ip_unlock(port);
                    708:                return KERN_INVALID_RIGHT;
                    709:        }
                    710: 
                    711:        *typep = (unsigned int) ip_kotype(port);
                    712:        *addrp = (vm_offset_t) port->ip_kobject;
                    713:        ip_unlock(port);
                    714:        return KERN_SUCCESS;
                    715: }

unix.superglobalmegacorp.com

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