|
|
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, ©); ! 216: assert(kr == KERN_SUCCESS); ! 217: #else /* MACH_OLD_VM_COPY */ ! 218: kr = vm_map_copyin(ipc_kernel_map, addr, used, ! 219: TRUE, ©); ! 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, ©); ! 308: assert(kr == KERN_SUCCESS); ! 309: #else /* MACH_OLD_VM_COPY */ ! 310: kr = vm_map_copyin(ipc_kernel_map, addr, used, ! 311: TRUE, ©); ! 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, ©); ! 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, ©); ! 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, ©); ! 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, ©); ! 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.