X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/e5568f75972dfc723778653c11cb6b4dc825716a..4a3eedf9ecc9bbe3f3a5c6ce5e53ad199d639d32:/osfmk/ipc/mach_debug.c diff --git a/osfmk/ipc/mach_debug.c b/osfmk/ipc/mach_debug.c index ab6e47c9c..ed8745e3f 100644 --- a/osfmk/ipc/mach_debug.c +++ b/osfmk/ipc/mach_debug.c @@ -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 #include #include +#include +#include #include #include #include @@ -93,15 +101,22 @@ * 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, ©); - 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, ©); + 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, ©); + kr = vm_map_copyin(ipc_kernel_map, (vm_map_address_t)table_addr, + (vm_map_size_t)table_size, TRUE, ©); 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, ©); + kr = vm_map_copyin(ipc_kernel_map, (vm_map_address_t)tree_addr, + (vm_map_size_t)tree_size, TRUE, ©); 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 */