1/* 2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* 29 * @OSF_COPYRIGHT@ 30 */ 31/* 32 * Mach Operating System 33 * Copyright (c) 1991,1990 Carnegie Mellon University 34 * All Rights Reserved. 35 * 36 * Permission to use, copy, modify and distribute this software and its 37 * documentation is hereby granted, provided that both the copyright 38 * notice and this permission notice appear in all copies of the 39 * software, derivative works or modified versions, and any portions 40 * thereof, and that both notices appear in supporting documentation. 41 * 42 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 43 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 44 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 45 * 46 * Carnegie Mellon requests users of this software to return to 47 * 48 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 49 * School of Computer Science 50 * Carnegie Mellon University 51 * Pittsburgh PA 15213-3890 52 * 53 * any improvements or extensions that they make and grant Carnegie Mellon 54 * the rights to redistribute these changes. 55 */ 56/* 57 */ 58/* 59 * File: vm/vm_debug.c. 60 * Author: Rich Draves 61 * Date: March, 1990 62 * 63 * Exported kernel calls. See mach_debug/mach_debug.defs. 64 */ 65#include <mach_vm_debug.h> 66#include <mach/kern_return.h> 67#include <mach/mach_host_server.h> 68#include <mach_debug/vm_info.h> 69#include <mach_debug/page_info.h> 70#include <mach_debug/hash_info.h> 71 72#if MACH_VM_DEBUG 73#include <mach/machine/vm_types.h> 74#include <mach/memory_object_types.h> 75#include <mach/vm_prot.h> 76#include <mach/vm_inherit.h> 77#include <mach/vm_param.h> 78#include <kern/thread.h> 79#include <vm/vm_map.h> 80#include <vm/vm_kern.h> 81#include <vm/vm_object.h> 82#include <kern/task.h> 83#include <kern/host.h> 84#include <ipc/ipc_port.h> 85#include <vm/vm_debug.h> 86#endif 87 88#if !MACH_VM_DEBUG 89#define __DEBUG_ONLY __unused 90#else /* !MACH_VM_DEBUG */ 91#define __DEBUG_ONLY 92#endif /* !MACH_VM_DEBUG */ 93 94#if VM32_SUPPORT 95 96#include <mach/vm32_map_server.h> 97#include <mach/vm_map.h> 98 99/* 100 * Routine: mach_vm_region_info [kernel call] 101 * Purpose: 102 * Retrieve information about a VM region, 103 * including info about the object chain. 104 * Conditions: 105 * Nothing locked. 106 * Returns: 107 * KERN_SUCCESS Retrieve region/object info. 108 * KERN_INVALID_TASK The map is null. 109 * KERN_NO_SPACE There is no entry at/after the address. 110 * KERN_RESOURCE_SHORTAGE Can't allocate memory. 111 */ 112 113kern_return_t 114vm32_region_info( 115 __DEBUG_ONLY vm_map_t map, 116 __DEBUG_ONLY vm32_offset_t address, 117 __DEBUG_ONLY vm_info_region_t *regionp, 118 __DEBUG_ONLY vm_info_object_array_t *objectsp, 119 __DEBUG_ONLY mach_msg_type_number_t *objectsCntp) 120{ 121#if !MACH_VM_DEBUG 122 return KERN_FAILURE; 123#else 124 vm_map_copy_t copy; 125 vm_offset_t addr; /* memory for OOL data */ 126 vm_size_t size; /* size of the memory */ 127 unsigned int room; /* room for this many objects */ 128 unsigned int used; /* actually this many objects */ 129 vm_info_region_t region; 130 kern_return_t kr; 131 132 if (map == VM_MAP_NULL) 133 return KERN_INVALID_TASK; 134 135 size = 0; /* no memory allocated yet */ 136 137 for (;;) { 138 vm_map_t cmap; /* current map in traversal */ 139 vm_map_t nmap; /* next map to look at */ 140 vm_map_entry_t entry; 141 vm_object_t object, cobject, nobject; 142 143 /* nothing is locked */ 144 145 vm_map_lock_read(map); 146 for (cmap = map;; cmap = nmap) { 147 /* cmap is read-locked */ 148 149 if (!vm_map_lookup_entry(cmap, 150 (vm_map_address_t)address, &entry)) { 151 152 entry = entry->vme_next; 153 if (entry == vm_map_to_entry(cmap)) { 154 vm_map_unlock_read(cmap); 155 if (size != 0) 156 kmem_free(ipc_kernel_map, 157 addr, size); 158 return KERN_NO_SPACE; 159 } 160 } 161 162 if (entry->is_sub_map) 163 nmap = entry->object.sub_map; 164 else 165 break; 166 167 /* move down to the lower map */ 168 169 vm_map_lock_read(nmap); 170 vm_map_unlock_read(cmap); 171 } 172 173 /* cmap is read-locked; we have a real entry */ 174 175 object = entry->object.vm_object; 176 region.vir_start = (natural_t) entry->vme_start; 177 region.vir_end = (natural_t) entry->vme_end; 178 region.vir_object = (natural_t)(uintptr_t) object; 179 region.vir_offset = (natural_t) entry->offset; 180 region.vir_needs_copy = entry->needs_copy; 181 region.vir_protection = entry->protection; 182 region.vir_max_protection = entry->max_protection; 183 region.vir_inheritance = entry->inheritance; 184 region.vir_wired_count = entry->wired_count; 185 region.vir_user_wired_count = entry->user_wired_count; 186 187 used = 0; 188 room = (unsigned int) (size / sizeof(vm_info_object_t)); 189 190 if (object == VM_OBJECT_NULL) { 191 vm_map_unlock_read(cmap); 192 /* no memory needed */ 193 break; 194 } 195 196 vm_object_lock(object); 197 vm_map_unlock_read(cmap); 198 199 for (cobject = object;; cobject = nobject) { 200 /* cobject is locked */ 201 202 if (used < room) { 203 vm_info_object_t *vio = 204 &((vm_info_object_t *) addr)[used]; 205 206 vio->vio_object = 207 (natural_t)(uintptr_t) cobject; 208 vio->vio_size = 209 (natural_t) cobject->vo_size; 210 vio->vio_ref_count = 211 cobject->ref_count; 212 vio->vio_resident_page_count = 213 cobject->resident_page_count; 214 vio->vio_copy = 215 (natural_t)(uintptr_t) cobject->copy; 216 vio->vio_shadow = 217 (natural_t)(uintptr_t) cobject->shadow; 218 vio->vio_shadow_offset = 219 (natural_t) cobject->vo_shadow_offset; 220 vio->vio_paging_offset = 221 (natural_t) cobject->paging_offset; 222 vio->vio_copy_strategy = 223 cobject->copy_strategy; 224 vio->vio_last_alloc = 225 (vm_offset_t) cobject->last_alloc; 226 vio->vio_paging_in_progress = 227 cobject->paging_in_progress + 228 cobject->activity_in_progress; 229 vio->vio_pager_created = 230 cobject->pager_created; 231 vio->vio_pager_initialized = 232 cobject->pager_initialized; 233 vio->vio_pager_ready = 234 cobject->pager_ready; 235 vio->vio_can_persist = 236 cobject->can_persist; 237 vio->vio_internal = 238 cobject->internal; 239 vio->vio_temporary = 240 cobject->temporary; 241 vio->vio_alive = 242 cobject->alive; 243 vio->vio_purgable = 244 (cobject->purgable != VM_PURGABLE_DENY); 245 vio->vio_purgable_volatile = 246 (cobject->purgable == VM_PURGABLE_VOLATILE || 247 cobject->purgable == VM_PURGABLE_EMPTY); 248 } 249 250 used++; 251 nobject = cobject->shadow; 252 if (nobject == VM_OBJECT_NULL) { 253 vm_object_unlock(cobject); 254 break; 255 } 256 257 vm_object_lock(nobject); 258 vm_object_unlock(cobject); 259 } 260 261 /* nothing locked */ 262 263 if (used <= room) 264 break; 265 266 /* must allocate more memory */ 267 268 if (size != 0) 269 kmem_free(ipc_kernel_map, addr, size); 270 size = vm_map_round_page(2 * used * sizeof(vm_info_object_t), 271 VM_MAP_PAGE_MASK(ipc_kernel_map)); 272 273 kr = vm_allocate(ipc_kernel_map, &addr, size, VM_FLAGS_ANYWHERE); 274 if (kr != KERN_SUCCESS) 275 return KERN_RESOURCE_SHORTAGE; 276 277 kr = vm_map_wire( 278 ipc_kernel_map, 279 vm_map_trunc_page(addr, 280 VM_MAP_PAGE_MASK(ipc_kernel_map)), 281 vm_map_round_page(addr + size, 282 VM_MAP_PAGE_MASK(ipc_kernel_map)), 283 VM_PROT_READ|VM_PROT_WRITE, 284 FALSE); 285 assert(kr == KERN_SUCCESS); 286 } 287 288 /* free excess memory; make remaining memory pageable */ 289 290 if (used == 0) { 291 copy = VM_MAP_COPY_NULL; 292 293 if (size != 0) 294 kmem_free(ipc_kernel_map, addr, size); 295 } else { 296 vm_size_t size_used = 297 vm_map_round_page(used * sizeof(vm_info_object_t), 298 VM_MAP_PAGE_MASK(ipc_kernel_map)); 299 300 kr = vm_map_unwire( 301 ipc_kernel_map, 302 vm_map_trunc_page(addr, 303 VM_MAP_PAGE_MASK(ipc_kernel_map)), 304 vm_map_round_page(addr + size_used, 305 VM_MAP_PAGE_MASK(ipc_kernel_map)), 306 FALSE); 307 assert(kr == KERN_SUCCESS); 308 309 kr = vm_map_copyin(ipc_kernel_map, (vm_map_address_t)addr, 310 (vm_map_size_t)size_used, TRUE, ©); 311 assert(kr == KERN_SUCCESS); 312 313 if (size != size_used) 314 kmem_free(ipc_kernel_map, 315 addr + size_used, size - size_used); 316 } 317 318 *regionp = region; 319 *objectsp = (vm_info_object_array_t) copy; 320 *objectsCntp = used; 321 return KERN_SUCCESS; 322#endif /* MACH_VM_DEBUG */ 323} 324 325/* 326 * Temporary call for 64 bit data path interface transiotion 327 */ 328 329kern_return_t 330vm32_region_info_64( 331 __DEBUG_ONLY vm_map_t map, 332 __DEBUG_ONLY vm32_offset_t address, 333 __DEBUG_ONLY vm_info_region_64_t *regionp, 334 __DEBUG_ONLY vm_info_object_array_t *objectsp, 335 __DEBUG_ONLY mach_msg_type_number_t *objectsCntp) 336{ 337#if !MACH_VM_DEBUG 338 return KERN_FAILURE; 339#else 340 vm_map_copy_t copy; 341 vm_offset_t addr; /* memory for OOL data */ 342 vm_size_t size; /* size of the memory */ 343 unsigned int room; /* room for this many objects */ 344 unsigned int used; /* actually this many objects */ 345 vm_info_region_64_t region; 346 kern_return_t kr; 347 348 if (map == VM_MAP_NULL) 349 return KERN_INVALID_TASK; 350 351 size = 0; /* no memory allocated yet */ 352 353 for (;;) { 354 vm_map_t cmap; /* current map in traversal */ 355 vm_map_t nmap; /* next map to look at */ 356 vm_map_entry_t entry; 357 vm_object_t object, cobject, nobject; 358 359 /* nothing is locked */ 360 361 vm_map_lock_read(map); 362 for (cmap = map;; cmap = nmap) { 363 /* cmap is read-locked */ 364 365 if (!vm_map_lookup_entry(cmap, address, &entry)) { 366 entry = entry->vme_next; 367 if (entry == vm_map_to_entry(cmap)) { 368 vm_map_unlock_read(cmap); 369 if (size != 0) 370 kmem_free(ipc_kernel_map, 371 addr, size); 372 return KERN_NO_SPACE; 373 } 374 } 375 376 if (entry->is_sub_map) 377 nmap = entry->object.sub_map; 378 else 379 break; 380 381 /* move down to the lower map */ 382 383 vm_map_lock_read(nmap); 384 vm_map_unlock_read(cmap); 385 } 386 387 /* cmap is read-locked; we have a real entry */ 388 389 object = entry->object.vm_object; 390 region.vir_start = (natural_t) entry->vme_start; 391 region.vir_end = (natural_t) entry->vme_end; 392 region.vir_object = (natural_t)(uintptr_t) object; 393 region.vir_offset = entry->offset; 394 region.vir_needs_copy = entry->needs_copy; 395 region.vir_protection = entry->protection; 396 region.vir_max_protection = entry->max_protection; 397 region.vir_inheritance = entry->inheritance; 398 region.vir_wired_count = entry->wired_count; 399 region.vir_user_wired_count = entry->user_wired_count; 400 401 used = 0; 402 room = (unsigned int) (size / sizeof(vm_info_object_t)); 403 404 if (object == VM_OBJECT_NULL) { 405 vm_map_unlock_read(cmap); 406 /* no memory needed */ 407 break; 408 } 409 410 vm_object_lock(object); 411 vm_map_unlock_read(cmap); 412 413 for (cobject = object;; cobject = nobject) { 414 /* cobject is locked */ 415 416 if (used < room) { 417 vm_info_object_t *vio = 418 &((vm_info_object_t *) addr)[used]; 419 420 vio->vio_object = 421 (natural_t)(uintptr_t) cobject; 422 vio->vio_size = 423 (natural_t) cobject->vo_size; 424 vio->vio_ref_count = 425 cobject->ref_count; 426 vio->vio_resident_page_count = 427 cobject->resident_page_count; 428 vio->vio_copy = 429 (natural_t)(uintptr_t) cobject->copy; 430 vio->vio_shadow = 431 (natural_t)(uintptr_t) cobject->shadow; 432 vio->vio_shadow_offset = 433 (natural_t) cobject->vo_shadow_offset; 434 vio->vio_paging_offset = 435 (natural_t) cobject->paging_offset; 436 vio->vio_copy_strategy = 437 cobject->copy_strategy; 438 vio->vio_last_alloc = 439 (vm_offset_t) cobject->last_alloc; 440 vio->vio_paging_in_progress = 441 cobject->paging_in_progress + 442 cobject->activity_in_progress; 443 vio->vio_pager_created = 444 cobject->pager_created; 445 vio->vio_pager_initialized = 446 cobject->pager_initialized; 447 vio->vio_pager_ready = 448 cobject->pager_ready; 449 vio->vio_can_persist = 450 cobject->can_persist; 451 vio->vio_internal = 452 cobject->internal; 453 vio->vio_temporary = 454 cobject->temporary; 455 vio->vio_alive = 456 cobject->alive; 457 vio->vio_purgable = 458 (cobject->purgable != VM_PURGABLE_DENY); 459 vio->vio_purgable_volatile = 460 (cobject->purgable == VM_PURGABLE_VOLATILE || 461 cobject->purgable == VM_PURGABLE_EMPTY); 462 } 463 464 used++; 465 nobject = cobject->shadow; 466 if (nobject == VM_OBJECT_NULL) { 467 vm_object_unlock(cobject); 468 break; 469 } 470 471 vm_object_lock(nobject); 472 vm_object_unlock(cobject); 473 } 474 475 /* nothing locked */ 476 477 if (used <= room) 478 break; 479 480 /* must allocate more memory */ 481 482 if (size != 0) 483 kmem_free(ipc_kernel_map, addr, size); 484 size = vm_map_round_page(2 * used * sizeof(vm_info_object_t), 485 VM_MAP_PAGE_MASK(ipc_kernel_map)); 486 487 kr = vm_allocate(ipc_kernel_map, &addr, size, VM_FLAGS_ANYWHERE); 488 if (kr != KERN_SUCCESS) 489 return KERN_RESOURCE_SHORTAGE; 490 491 kr = vm_map_wire( 492 ipc_kernel_map, 493 vm_map_trunc_page(addr, 494 VM_MAP_PAGE_MASK(ipc_kernel_map)), 495 vm_map_round_page(addr + size, 496 VM_MAP_PAGE_MASK(ipc_kernel_map)), 497 VM_PROT_READ|VM_PROT_WRITE, 498 FALSE); 499 assert(kr == KERN_SUCCESS); 500 } 501 502 /* free excess memory; make remaining memory pageable */ 503 504 if (used == 0) { 505 copy = VM_MAP_COPY_NULL; 506 507 if (size != 0) 508 kmem_free(ipc_kernel_map, addr, size); 509 } else { 510 vm_size_t size_used = 511 vm_map_round_page(used * sizeof(vm_info_object_t), 512 VM_MAP_PAGE_MASK(ipc_kernel_map)); 513 514 kr = vm_map_unwire( 515 ipc_kernel_map, 516 vm_map_trunc_page(addr, 517 VM_MAP_PAGE_MASK(ipc_kernel_map)), 518 vm_map_round_page(addr + size_used, 519 VM_MAP_PAGE_MASK(ipc_kernel_map)), 520 FALSE); 521 assert(kr == KERN_SUCCESS); 522 523 kr = vm_map_copyin(ipc_kernel_map, (vm_map_address_t)addr, 524 (vm_map_size_t)size_used, TRUE, ©); 525 assert(kr == KERN_SUCCESS); 526 527 if (size != size_used) 528 kmem_free(ipc_kernel_map, 529 addr + size_used, size - size_used); 530 } 531 532 *regionp = region; 533 *objectsp = (vm_info_object_array_t) copy; 534 *objectsCntp = used; 535 return KERN_SUCCESS; 536#endif /* MACH_VM_DEBUG */ 537} 538/* 539 * Return an array of virtual pages that are mapped to a task. 540 */ 541kern_return_t 542vm32_mapped_pages_info( 543 __DEBUG_ONLY vm_map_t map, 544 __DEBUG_ONLY page_address_array_t *pages, 545 __DEBUG_ONLY mach_msg_type_number_t *pages_count) 546{ 547#if !MACH_VM_DEBUG 548 return KERN_FAILURE; 549#else 550 pmap_t pmap; 551 vm_size_t size, size_used; 552 unsigned int actual, space; 553 page_address_array_t list; 554 vm_offset_t addr; 555 556 if (map == VM_MAP_NULL) 557 return (KERN_INVALID_ARGUMENT); 558 559 pmap = map->pmap; 560 size = pmap_resident_count(pmap) * sizeof(vm_offset_t); 561 size = vm_map_round_page(size, 562 VM_MAP_PAGE_MASK(ipc_kernel_map)); 563 564 for (;;) { 565 (void) vm_allocate(ipc_kernel_map, &addr, size, VM_FLAGS_ANYWHERE); 566 (void) vm_map_unwire( 567 ipc_kernel_map, 568 vm_map_trunc_page(addr, 569 VM_MAP_PAGE_MASK(ipc_kernel_map)), 570 vm_map_round_page(addr + size, 571 VM_MAP_PAGE_MASK(ipc_kernel_map)), 572 FALSE); 573 574 list = (page_address_array_t) addr; 575 space = (unsigned int) (size / sizeof(vm_offset_t)); 576 577 actual = pmap_list_resident_pages(pmap, 578 list, 579 space); 580 if (actual <= space) 581 break; 582 583 /* 584 * Free memory if not enough 585 */ 586 (void) kmem_free(ipc_kernel_map, addr, size); 587 588 /* 589 * Try again, doubling the size 590 */ 591 size = vm_map_round_page(actual * sizeof(vm_offset_t), 592 VM_MAP_PAGE_MASK(ipc_kernel_map)); 593 } 594 if (actual == 0) { 595 *pages = 0; 596 *pages_count = 0; 597 (void) kmem_free(ipc_kernel_map, addr, size); 598 } 599 else { 600 *pages_count = actual; 601 size_used = vm_map_round_page(actual * sizeof(vm_offset_t), 602 VM_MAP_PAGE_MASK(ipc_kernel_map)); 603 (void) vm_map_wire( 604 ipc_kernel_map, 605 vm_map_trunc_page(addr, 606 VM_MAP_PAGE_MASK(ipc_kernel_map)), 607 vm_map_round_page(addr + size, 608 VM_MAP_PAGE_MASK(ipc_kernel_map)), 609 VM_PROT_READ|VM_PROT_WRITE, 610 FALSE); 611 (void) vm_map_copyin(ipc_kernel_map, 612 (vm_map_address_t)addr, 613 (vm_map_size_t)size_used, 614 TRUE, 615 (vm_map_copy_t *)pages); 616 if (size_used != size) { 617 (void) kmem_free(ipc_kernel_map, 618 addr + size_used, 619 size - size_used); 620 } 621 } 622 623 return (KERN_SUCCESS); 624#endif /* MACH_VM_DEBUG */ 625} 626 627#endif /* VM32_SUPPORT */ 628 629/* 630 * Routine: host_virtual_physical_table_info 631 * Purpose: 632 * Return information about the VP table. 633 * Conditions: 634 * Nothing locked. Obeys CountInOut protocol. 635 * Returns: 636 * KERN_SUCCESS Returned information. 637 * KERN_INVALID_HOST The host is null. 638 * KERN_RESOURCE_SHORTAGE Couldn't allocate memory. 639 */ 640 641kern_return_t 642host_virtual_physical_table_info( 643 __DEBUG_ONLY host_t host, 644 __DEBUG_ONLY hash_info_bucket_array_t *infop, 645 __DEBUG_ONLY mach_msg_type_number_t *countp) 646{ 647#if !MACH_VM_DEBUG 648 return KERN_FAILURE; 649#else 650 vm_offset_t addr; 651 vm_size_t size = 0; 652 hash_info_bucket_t *info; 653 unsigned int potential, actual; 654 kern_return_t kr; 655 656 if (host == HOST_NULL) 657 return KERN_INVALID_HOST; 658 659 /* start with in-line data */ 660 661 info = *infop; 662 potential = *countp; 663 664 for (;;) { 665 actual = vm_page_info(info, potential); 666 if (actual <= potential) 667 break; 668 669 /* allocate more memory */ 670 671 if (info != *infop) 672 kmem_free(ipc_kernel_map, addr, size); 673 674 size = vm_map_round_page(actual * sizeof *info, 675 VM_MAP_PAGE_MASK(ipc_kernel_map)); 676 kr = kmem_alloc_pageable(ipc_kernel_map, &addr, size); 677 if (kr != KERN_SUCCESS) 678 return KERN_RESOURCE_SHORTAGE; 679 680 info = (hash_info_bucket_t *) addr; 681 potential = (unsigned int) (size/sizeof (*info)); 682 } 683 684 if (info == *infop) { 685 /* data fit in-line; nothing to deallocate */ 686 687 *countp = actual; 688 } else if (actual == 0) { 689 kmem_free(ipc_kernel_map, addr, size); 690 691 *countp = 0; 692 } else { 693 vm_map_copy_t copy; 694 vm_size_t used; 695 696 used = vm_map_round_page(actual * sizeof *info, 697 VM_MAP_PAGE_MASK(ipc_kernel_map)); 698 699 if (used != size) 700 kmem_free(ipc_kernel_map, addr + used, size - used); 701 702 kr = vm_map_copyin(ipc_kernel_map, (vm_map_address_t)addr, 703 (vm_map_size_t)used, TRUE, ©); 704 assert(kr == KERN_SUCCESS); 705 706 *infop = (hash_info_bucket_t *) copy; 707 *countp = actual; 708 } 709 710 return KERN_SUCCESS; 711#endif /* MACH_VM_DEBUG */ 712} 713