]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/ipc/mach_debug.c
xnu-1228.3.13.tar.gz
[apple/xnu.git] / osfmk / ipc / mach_debug.c
index ab6e47c9c1e99abbac029121e65c652ecebe3308..ed8745e3f7d1e4014436073dfc47326253a1a504 100644 (file)
@@ -1,23 +1,29 @@
 /*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
  *
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /*
  * @OSF_COPYRIGHT@
@@ -71,6 +77,8 @@
 #include <kern/misc_protos.h>
 #include <vm/vm_map.h>
 #include <vm/vm_kern.h>
+#include <ipc/port.h>
+#include <ipc/ipc_types.h>
 #include <ipc/ipc_space.h>
 #include <ipc/ipc_port.h>
 #include <ipc/ipc_hash.h>
  *             KERN_INVALID_RIGHT      Name doesn't denote receive rights.
  */
 
+#if !MACH_IPC_DEBUG
+kern_return_t
+mach_port_get_srights(
+       __unused ipc_space_t            space,
+       __unused mach_port_name_t       name,
+       __unused mach_port_rights_t     *srightsp)
+{
+        return KERN_FAILURE;
+}
+#else
 kern_return_t
 mach_port_get_srights(
        ipc_space_t             space,
        mach_port_name_t        name,
        mach_port_rights_t      *srightsp)
 {
-#if !MACH_IPC_DEBUG
-        return KERN_FAILURE;
-#else
        ipc_port_t port;
        kern_return_t kr;
        mach_port_rights_t srights;
@@ -119,8 +134,8 @@ mach_port_get_srights(
 
        *srightsp = srights;
        return KERN_SUCCESS;
-#endif /* MACH_IPC_DEBUG */
 }
+#endif /* MACH_IPC_DEBUG */
 
 /*
  *     Routine:        host_ipc_hash_info
@@ -134,19 +149,27 @@ mach_port_get_srights(
  *             KERN_RESOURCE_SHORTAGE  Couldn't allocate memory.
  */
 
+#if !MACH_IPC_DEBUG
 kern_return_t
 host_ipc_hash_info(
-       host_t                          host,
-       hash_info_bucket_array_t        *infop,
-       mach_msg_type_number_t          *countp)
+       __unused host_t                 host,
+       __unused hash_info_bucket_array_t       *infop,
+       __unused mach_msg_type_number_t         *countp)
 {
-#if !MACH_IPC_DEBUG
         return KERN_FAILURE;
+}
 #else
+kern_return_t
+host_ipc_hash_info(
+       host_t                                  host,
+       hash_info_bucket_array_t                *infop,
+       mach_msg_type_number_t          *countp)
+{
+       vm_map_copy_t copy;
        vm_offset_t addr;
        vm_size_t size;
        hash_info_bucket_t *info;
-       unsigned int potential, actual;
+       natural_t count;
        kern_return_t kr;
 
        if (host == HOST_NULL)
@@ -154,56 +177,27 @@ host_ipc_hash_info(
 
        /* start with in-line data */
 
-       info = *infop;
-       potential = *countp;
-
-       for (;;) {
-               actual = ipc_hash_info(info, potential);
-               if (actual <= potential)
-                       break;
-
-               /* allocate more memory */
-
-               if (info != *infop)
-                       kmem_free(ipc_kernel_map, addr, size);
-
-               size = round_page_32(actual * sizeof *info);
-               kr = kmem_alloc_pageable(ipc_kernel_map, &addr, size);
-               if (kr != KERN_SUCCESS)
-                       return KERN_RESOURCE_SHORTAGE;
-
-               info = (hash_info_bucket_t *) addr;
-               potential = size/sizeof *info;
-       }
-
-       if (info == *infop) {
-               /* data fit in-line; nothing to deallocate */
-
-               *countp = actual;
-       } else if (actual == 0) {
-               kmem_free(ipc_kernel_map, addr, size);
-
-               *countp = 0;
-       } else {
-               vm_map_copy_t copy;
-               vm_size_t used;
-
-               used = round_page_32(actual * sizeof *info);
+       count = ipc_hash_size();
+       size = round_page(count * sizeof(hash_info_bucket_t));
+       kr = kmem_alloc_pageable(ipc_kernel_map, &addr, size);
+       if (kr != KERN_SUCCESS)
+               return KERN_RESOURCE_SHORTAGE;
 
-               if (used != size)
-                       kmem_free(ipc_kernel_map, addr + used, size - used);
+       info = (hash_info_bucket_t *) addr;
+       count = ipc_hash_info(info, count);
 
-               kr = vm_map_copyin(ipc_kernel_map, addr, used,
-                                  TRUE, &copy);
-               assert(kr == KERN_SUCCESS);
+       if (size > count * sizeof(hash_info_bucket_t))
+               bzero((char *)&info[count], size - count * sizeof(hash_info_bucket_t));
 
-               *infop = (hash_info_bucket_t *) copy;
-               *countp = actual;
-       }
+       kr = vm_map_copyin(ipc_kernel_map, (vm_map_address_t)addr, 
+                          (vm_map_size_t)size, TRUE, &copy);
+       assert(kr == KERN_SUCCESS);
 
+       *infop = (hash_info_bucket_t *) copy;
+       *countp = count;
        return KERN_SUCCESS;
-#endif /* MACH_IPC_DEBUG */
 }
+#endif /* MACH_IPC_DEBUG */
 
 /*
  *     Routine:        mach_port_space_info
@@ -218,6 +212,19 @@ host_ipc_hash_info(
  *             KERN_RESOURCE_SHORTAGE  Couldn't allocate memory.
  */
 
+#if !MACH_IPC_DEBUG
+kern_return_t
+mach_port_space_info(
+       __unused ipc_space_t                    space,
+       __unused ipc_info_space_t               *infop,
+       __unused ipc_info_name_array_t  *tablep,
+       __unused mach_msg_type_number_t         *tableCntp,
+       __unused ipc_info_tree_name_array_t *treep,
+       __unused mach_msg_type_number_t         *treeCntp)
+{
+        return KERN_FAILURE;
+}
+#else
 kern_return_t
 mach_port_space_info(
        ipc_space_t                     space,
@@ -227,100 +234,78 @@ mach_port_space_info(
        ipc_info_tree_name_array_t      *treep,
        mach_msg_type_number_t          *treeCntp)
 {
-#if !MACH_IPC_DEBUG
-        return KERN_FAILURE;
-#else
        ipc_info_name_t *table_info;
-       unsigned int table_potential, table_actual;
        vm_offset_t table_addr;
-       vm_size_t table_size;
+       vm_size_t table_size, table_size_needed;
        ipc_info_tree_name_t *tree_info;
-       unsigned int tree_potential, tree_actual;
        vm_offset_t tree_addr;
-       vm_size_t tree_size;
+       vm_size_t tree_size, tree_size_needed;
        ipc_tree_entry_t tentry;
        ipc_entry_t table;
        ipc_entry_num_t tsize;
        mach_port_index_t index;
        kern_return_t kr;
-       ipc_entry_bits_t *capability;
+       vm_map_copy_t copy;
+
 
        if (space == IS_NULL)
                return KERN_INVALID_TASK;
 
        /* start with in-line memory */
 
-       table_info = *tablep;
-       table_potential = *tableCntp;
-       tree_info = *treep;
-       tree_potential = *treeCntp;
+       table_size = 0;
+       tree_size = 0;
 
        for (;;) {
                is_read_lock(space);
                if (!space->is_active) {
                        is_read_unlock(space);
-                       if (table_info != *tablep)
+                       if (table_size != 0)
                                kmem_free(ipc_kernel_map,
                                          table_addr, table_size);
-                       if (tree_info != *treep)
+                       if (tree_size != 0)
                                kmem_free(ipc_kernel_map,
                                          tree_addr, tree_size);
                        return KERN_INVALID_TASK;
                }
 
-               table_actual = space->is_table_size;
-               tree_actual = space->is_tree_total;
+               table_size_needed = round_page(space->is_table_size
+                                              * sizeof(ipc_info_name_t));
+               tree_size_needed = round_page(space->is_tree_total
+                                             * sizeof(ipc_info_tree_name_t));
 
-               if ((table_actual <= table_potential) &&
-                   (tree_actual <= tree_potential))
+               if ((table_size_needed == table_size) &&
+                   (tree_size_needed == tree_size))
                        break;
 
                is_read_unlock(space);
 
-               if (table_actual > table_potential) {
-                       if (table_info != *tablep)
-                               kmem_free(ipc_kernel_map,
-                                         table_addr, table_size);
-
-                       table_size = round_page_32(table_actual *
-                                               sizeof *table_info);
-                       kr = kmem_alloc(ipc_kernel_map,
-                                       &table_addr, table_size);
+               if (table_size != table_size_needed) {
+                       if (table_size != 0)
+                               kmem_free(ipc_kernel_map, table_addr, table_size);
+                       kr = kmem_alloc(ipc_kernel_map, &table_addr, table_size_needed);
                        if (kr != KERN_SUCCESS) {
-                               if (tree_info != *treep)
-                                       kmem_free(ipc_kernel_map,
-                                                 tree_addr, tree_size);
-
+                               if (tree_size != 0)
+                                       kmem_free(ipc_kernel_map, tree_addr, tree_size);
                                return KERN_RESOURCE_SHORTAGE;
                        }
-
-                       table_info = (ipc_info_name_t *) table_addr;
-                       table_potential = table_size/sizeof *table_info;
+                       table_size = table_size_needed;
                }
-
-               if (tree_actual > tree_potential) {
-                       if (tree_info != *treep)
-                               kmem_free(ipc_kernel_map,
-                                         tree_addr, tree_size);
-
-                       tree_size = round_page_32(tree_actual *
-                                              sizeof *tree_info);
-                       kr = kmem_alloc(ipc_kernel_map,
-                                       &tree_addr, tree_size);
+               if (tree_size != tree_size_needed) {
+                       if (tree_size != 0)
+                               kmem_free(ipc_kernel_map, tree_addr, tree_size);
+                       kr = kmem_alloc(ipc_kernel_map, &tree_addr, tree_size_needed);
                        if (kr != KERN_SUCCESS) {
-                               if (table_info != *tablep)
-                                       kmem_free(ipc_kernel_map,
-                                                 table_addr, table_size);
-
+                               if (table_size != 0)
+                                       kmem_free(ipc_kernel_map, table_addr, table_size);
                                return KERN_RESOURCE_SHORTAGE;
                        }
-
-                       tree_info = (ipc_info_tree_name_t *) tree_addr;
-                       tree_potential = tree_size/sizeof *tree_info;
+                       tree_size = tree_size_needed;
                }
        }
        /* space is read-locked and active; we have enough wired memory */
 
+       /* get the overall space info */
        infop->iis_genno_mask = MACH_PORT_NGEN(MACH_PORT_DEAD);
        infop->iis_table_size = space->is_table_size;
        infop->iis_table_next = space->is_table_next->its_size;
@@ -328,9 +313,10 @@ mach_port_space_info(
        infop->iis_tree_small = space->is_tree_small;
        infop->iis_tree_hash = space->is_tree_hash;
 
+       /* walk the table for this space */
        table = space->is_table;
        tsize = space->is_table_size;
-
+       table_info = (ipc_info_name_array_t)table_addr;
        for (index = 0; index < tsize; index++) {
                ipc_info_name_t *iin = &table_info[index];
                ipc_entry_t entry = &table[index];
@@ -340,12 +326,16 @@ mach_port_space_info(
                iin->iin_name = MACH_PORT_MAKE(index, IE_BITS_GEN(bits));
                iin->iin_collision = (bits & IE_BITS_COLLISION) ? TRUE : FALSE;
                iin->iin_type = IE_BITS_TYPE(bits);
+               if (entry->ie_request)
+                       iin->iin_type |= MACH_PORT_TYPE_DNREQUEST;
                iin->iin_urefs = IE_BITS_UREFS(bits);
                iin->iin_object = (vm_offset_t) entry->ie_object;
                iin->iin_next = entry->ie_next;
                iin->iin_hash = entry->ie_index;
        }
 
+       /* walk the splay tree for this space */
+       tree_info = (ipc_info_tree_name_array_t)tree_addr;
        for (tentry = ipc_splay_traverse_start(&space->is_tree), index = 0;
             tentry != ITE_NULL;
             tentry = ipc_splay_traverse_next(&space->is_tree, FALSE)) {
@@ -359,6 +349,8 @@ mach_port_space_info(
                iin->iin_name = tentry->ite_name;
                iin->iin_collision = (bits & IE_BITS_COLLISION) ? TRUE : FALSE;
                iin->iin_type = IE_BITS_TYPE(bits);
+               if (entry->ie_request)
+                       iin->iin_type |= MACH_PORT_TYPE_DNREQUEST;
                iin->iin_urefs = IE_BITS_UREFS(bits);
                iin->iin_object = (vm_offset_t) entry->ie_object;
                iin->iin_next = entry->ie_next;
@@ -378,85 +370,46 @@ mach_port_space_info(
        ipc_splay_traverse_finish(&space->is_tree);
        is_read_unlock(space);
 
-       if (table_info == *tablep) {
-               /* data fit in-line; nothing to deallocate */
-
-               *tableCntp = table_actual;
-       } else if (table_actual == 0) {
-               kmem_free(ipc_kernel_map, table_addr, table_size);
+       /* prepare the table out-of-line data for return */
+       if (table_size > 0) {
+               if (table_size > infop->iis_table_size * sizeof(ipc_info_name_t))
+                       bzero((char *)&table_info[infop->iis_table_size],
+                             table_size - infop->iis_table_size * sizeof(ipc_info_name_t));
 
-               *tableCntp = 0;
-       } else {
-               vm_size_t size_used, rsize_used;
-               vm_map_copy_t copy;
-
-               /* kmem_alloc doesn't zero memory */
-
-               size_used = table_actual * sizeof *table_info;
-               rsize_used = round_page_32(size_used);
-
-               if (rsize_used != table_size)
-                       kmem_free(ipc_kernel_map,
-                                 table_addr + rsize_used,
-                                 table_size - rsize_used);
-
-               if (size_used != rsize_used)
-                       bzero((char *) (table_addr + size_used),
-                             rsize_used - size_used);
-
-               kr = vm_map_unwire(ipc_kernel_map, table_addr,
-                                  table_addr + rsize_used, FALSE);
+               kr = vm_map_unwire(ipc_kernel_map, vm_map_trunc_page(table_addr),
+                                  vm_map_round_page(table_addr + table_size), FALSE);
                assert(kr == KERN_SUCCESS);
-
-               kr = vm_map_copyin(ipc_kernel_map, table_addr, rsize_used,
-                                  TRUE, &copy);
+               kr = vm_map_copyin(ipc_kernel_map, (vm_map_address_t)table_addr, 
+                                  (vm_map_size_t)table_size, TRUE, &copy);
                assert(kr == KERN_SUCCESS);
-
-               *tablep = (ipc_info_name_t *) copy;
-               *tableCntp = table_actual;
-       }
-
-       if (tree_info == *treep) {
-               /* data fit in-line; nothing to deallocate */
-
-               *treeCntp = tree_actual;
-       } else if (tree_actual == 0) {
-               kmem_free(ipc_kernel_map, tree_addr, tree_size);
-
-               *treeCntp = 0;
+               *tablep = (ipc_info_name_t *)copy;
+               *tableCntp = infop->iis_table_size;
        } else {
-               vm_size_t size_used, rsize_used;
-               vm_map_copy_t copy;
-
-               /* kmem_alloc doesn't zero memory */
-
-               size_used = tree_actual * sizeof *tree_info;
-               rsize_used = round_page_32(size_used);
-
-               if (rsize_used != tree_size)
-                       kmem_free(ipc_kernel_map,
-                                 tree_addr + rsize_used,
-                                 tree_size - rsize_used);
+               *tablep = (ipc_info_name_t *)0;
+               *tableCntp = 0;
+       }
 
-               if (size_used != rsize_used)
-                       bzero((char *) (tree_addr + size_used),
-                             rsize_used - size_used);
+       /* prepare the tree out-of-line data for return */
+       if (tree_size > 0) {
+               if (tree_size > infop->iis_tree_size * sizeof(ipc_info_tree_name_t))
+                       bzero((char *)&tree_info[infop->iis_tree_size],
+                             tree_size - infop->iis_tree_size * sizeof(ipc_info_tree_name_t));
 
-               kr = vm_map_unwire(ipc_kernel_map, tree_addr,
-                                  tree_addr + rsize_used, FALSE);
+               kr = vm_map_unwire(ipc_kernel_map, vm_map_trunc_page(tree_addr),
+                                  vm_map_round_page(tree_addr + tree_size), FALSE);
                assert(kr == KERN_SUCCESS);
-
-               kr = vm_map_copyin(ipc_kernel_map, tree_addr, rsize_used,
-                                  TRUE, &copy);
+               kr = vm_map_copyin(ipc_kernel_map, (vm_map_address_t)tree_addr, 
+                                  (vm_map_size_t)tree_size, TRUE, &copy);
                assert(kr == KERN_SUCCESS);
-
-               *treep = (ipc_info_tree_name_t *) copy;
-               *treeCntp = tree_actual;
+               *treep = (ipc_info_tree_name_t *)copy;
+               *treeCntp = infop->iis_tree_size;
+       } else {
+               *treep = (ipc_info_tree_name_t *)0;
+               *treeCntp = 0;
        }
-
        return KERN_SUCCESS;
-#endif /* MACH_IPC_DEBUG */
 }
+#endif /* MACH_IPC_DEBUG */
 
 /*
  *     Routine:        mach_port_dnrequest_info
@@ -473,16 +426,24 @@ mach_port_space_info(
  *             KERN_INVALID_RIGHT      Name doesn't denote receive rights.
  */
 
+#if !MACH_IPC_DEBUG
 kern_return_t
 mach_port_dnrequest_info(
-       ipc_space_t             space,
-       mach_port_name_t        name,
-       unsigned int            *totalp,
-       unsigned int            *usedp)
+       __unused ipc_space_t            space,
+       __unused mach_port_name_t       name,
+       __unused unsigned int   *totalp,
+       __unused unsigned int   *usedp)
 {
-#if !MACH_IPC_DEBUG
         return KERN_FAILURE;
+}
 #else
+kern_return_t
+mach_port_dnrequest_info(
+       ipc_space_t                     space,
+       mach_port_name_t                name,
+       unsigned int                    *totalp,
+       unsigned int                    *usedp)
+{
        unsigned int total, used;
        ipc_port_t port;
        kern_return_t kr;
@@ -517,8 +478,8 @@ mach_port_dnrequest_info(
        *totalp = total;
        *usedp = used;
        return KERN_SUCCESS;
-#endif /* MACH_IPC_DEBUG */
 }
+#endif /* MACH_IPC_DEBUG */
 
 /*
  *     Routine:        mach_port_kernel_object [kernel call]
@@ -536,20 +497,31 @@ mach_port_dnrequest_info(
  *                                     send or receive rights.
  */
 
+#if !MACH_IPC_DEBUG
 kern_return_t
 mach_port_kernel_object(
-       ipc_space_t             space,
-       mach_port_name_t        name,
-       unsigned int            *typep,
-       vm_offset_t             *addrp)
+       __unused ipc_space_t            space,
+       __unused mach_port_name_t       name,
+       __unused unsigned int   *typep,
+       __unused vm_offset_t            *addrp)
 {
-#if !MACH_IPC_DEBUG
         return KERN_FAILURE;
+}
 #else
+kern_return_t
+mach_port_kernel_object(
+       ipc_space_t                     space,
+       mach_port_name_t                name,
+       unsigned int                    *typep,
+       vm_offset_t                     *addrp)
+{
        ipc_entry_t entry;
        ipc_port_t port;
        kern_return_t kr;
 
+       if (space == IS_NULL)
+               return KERN_INVALID_TASK;
+
        kr = ipc_right_lookup_read(space, name, &entry);
        if (kr != KERN_SUCCESS)
                return kr;
@@ -576,5 +548,5 @@ mach_port_kernel_object(
        ip_unlock(port);
        return KERN_SUCCESS;
 
-#endif /* MACH_IPC_DEBUG */
 }
+#endif /* MACH_IPC_DEBUG */