|
|
1.1 ! root 1: /* ! 2: * Mach Operating System ! 3: * Copyright (c) 1991,1990,1989 Carnegie Mellon University ! 4: * All Rights Reserved. ! 5: * ! 6: * Permission to use, copy, modify and distribute this software and its ! 7: * documentation is hereby granted, provided that both the copyright ! 8: * notice and this permission notice appear in all copies of the ! 9: * software, derivative works or modified versions, and any portions ! 10: * thereof, and that both notices appear in supporting documentation. ! 11: * ! 12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 15: * ! 16: * Carnegie Mellon requests users of this software to return to ! 17: * ! 18: * Software Distribution Coordinator or [email protected] ! 19: * School of Computer Science ! 20: * Carnegie Mellon University ! 21: * Pittsburgh PA 15213-3890 ! 22: * ! 23: * any improvements or extensions that they make and grant Carnegie Mellon ! 24: * the rights to redistribute these changes. ! 25: */ ! 26: /* ! 27: * File: ipc/ipc_object.c ! 28: * Author: Rich Draves ! 29: * Date: 1989 ! 30: * ! 31: * Functions to manipulate IPC objects. ! 32: */ ! 33: ! 34: #include <mach_ipc_compat.h> ! 35: ! 36: #include <mach/boolean.h> ! 37: #include <mach/kern_return.h> ! 38: #include <mach/port.h> ! 39: #include <mach/message.h> ! 40: #include <ipc/port.h> ! 41: #include <ipc/ipc_space.h> ! 42: #include <ipc/ipc_entry.h> ! 43: #include <ipc/ipc_object.h> ! 44: #include <ipc/ipc_hash.h> ! 45: #include <ipc/ipc_right.h> ! 46: #include <ipc/ipc_notify.h> ! 47: #include <ipc/ipc_pset.h> ! 48: ! 49: zone_t ipc_object_zones[IOT_NUMBER]; ! 50: ! 51: ! 52: ! 53: /* ! 54: * Routine: ipc_object_reference ! 55: * Purpose: ! 56: * Take a reference to an object. ! 57: */ ! 58: ! 59: void ! 60: ipc_object_reference( ! 61: ipc_object_t object) ! 62: { ! 63: io_lock(object); ! 64: assert(object->io_references > 0); ! 65: io_reference(object); ! 66: io_unlock(object); ! 67: } ! 68: ! 69: /* ! 70: * Routine: ipc_object_release ! 71: * Purpose: ! 72: * Release a reference to an object. ! 73: */ ! 74: ! 75: void ! 76: ipc_object_release( ! 77: ipc_object_t object) ! 78: { ! 79: io_lock(object); ! 80: assert(object->io_references > 0); ! 81: io_release(object); ! 82: io_check_unlock(object); ! 83: } ! 84: ! 85: /* ! 86: * Routine: ipc_object_translate ! 87: * Purpose: ! 88: * Look up an object in a space. ! 89: * Conditions: ! 90: * Nothing locked before. If successful, the object ! 91: * is returned locked. The caller doesn't get a ref. ! 92: * Returns: ! 93: * KERN_SUCCESS Objected returned locked. ! 94: * KERN_INVALID_TASK The space is dead. ! 95: * KERN_INVALID_NAME The name doesn't denote a right. ! 96: * KERN_INVALID_RIGHT Name doesn't denote the correct right. ! 97: */ ! 98: ! 99: kern_return_t ! 100: ipc_object_translate( ! 101: ipc_space_t space, ! 102: mach_port_t name, ! 103: mach_port_right_t right, ! 104: ipc_object_t *objectp) ! 105: { ! 106: ipc_entry_t entry; ! 107: ipc_object_t object; ! 108: kern_return_t kr; ! 109: ! 110: kr = ipc_right_lookup_read(space, name, &entry); ! 111: if (kr != KERN_SUCCESS) ! 112: return kr; ! 113: /* space is read-locked and active */ ! 114: ! 115: if ((entry->ie_bits & MACH_PORT_TYPE(right)) == (mach_port_right_t) 0) { ! 116: is_read_unlock(space); ! 117: return KERN_INVALID_RIGHT; ! 118: } ! 119: ! 120: object = entry->ie_object; ! 121: assert(object != IO_NULL); ! 122: ! 123: io_lock(object); ! 124: is_read_unlock(space); ! 125: ! 126: *objectp = object; ! 127: return KERN_SUCCESS; ! 128: } ! 129: ! 130: /* ! 131: * Routine: ipc_object_alloc_dead ! 132: * Purpose: ! 133: * Allocate a dead-name entry. ! 134: * Conditions: ! 135: * Nothing locked. ! 136: * Returns: ! 137: * KERN_SUCCESS The dead name is allocated. ! 138: * KERN_INVALID_TASK The space is dead. ! 139: * KERN_NO_SPACE No room for an entry in the space. ! 140: * KERN_RESOURCE_SHORTAGE Couldn't allocate memory. ! 141: */ ! 142: ! 143: kern_return_t ! 144: ipc_object_alloc_dead( ! 145: ipc_space_t space, ! 146: mach_port_t *namep) ! 147: { ! 148: ipc_entry_t entry; ! 149: kern_return_t kr; ! 150: ! 151: ! 152: kr = ipc_entry_alloc(space, namep, &entry); ! 153: if (kr != KERN_SUCCESS) ! 154: return kr; ! 155: /* space is write-locked */ ! 156: ! 157: /* null object, MACH_PORT_TYPE_DEAD_NAME, 1 uref */ ! 158: ! 159: assert(entry->ie_object == IO_NULL); ! 160: entry->ie_bits |= MACH_PORT_TYPE_DEAD_NAME | 1; ! 161: ! 162: is_write_unlock(space); ! 163: return KERN_SUCCESS; ! 164: } ! 165: ! 166: /* ! 167: * Routine: ipc_object_alloc_dead_name ! 168: * Purpose: ! 169: * Allocate a dead-name entry, with a specific name. ! 170: * Conditions: ! 171: * Nothing locked. ! 172: * Returns: ! 173: * KERN_SUCCESS The dead name is allocated. ! 174: * KERN_INVALID_TASK The space is dead. ! 175: * KERN_NAME_EXISTS The name already denotes a right. ! 176: * KERN_RESOURCE_SHORTAGE Couldn't allocate memory. ! 177: */ ! 178: ! 179: kern_return_t ! 180: ipc_object_alloc_dead_name( ! 181: ipc_space_t space, ! 182: mach_port_t name) ! 183: { ! 184: ipc_entry_t entry; ! 185: kern_return_t kr; ! 186: ! 187: ! 188: kr = ipc_entry_alloc_name(space, name, &entry); ! 189: if (kr != KERN_SUCCESS) ! 190: return kr; ! 191: /* space is write-locked */ ! 192: ! 193: if (ipc_right_inuse(space, name, entry)) ! 194: return KERN_NAME_EXISTS; ! 195: ! 196: /* null object, MACH_PORT_TYPE_DEAD_NAME, 1 uref */ ! 197: ! 198: assert(entry->ie_object == IO_NULL); ! 199: entry->ie_bits |= MACH_PORT_TYPE_DEAD_NAME | 1; ! 200: ! 201: is_write_unlock(space); ! 202: return KERN_SUCCESS; ! 203: } ! 204: ! 205: /* ! 206: * Routine: ipc_object_alloc ! 207: * Purpose: ! 208: * Allocate an object. ! 209: * Conditions: ! 210: * Nothing locked. If successful, the object is returned locked. ! 211: * The caller doesn't get a reference for the object. ! 212: * Returns: ! 213: * KERN_SUCCESS The object is allocated. ! 214: * KERN_INVALID_TASK The space is dead. ! 215: * KERN_NO_SPACE No room for an entry in the space. ! 216: * KERN_RESOURCE_SHORTAGE Couldn't allocate memory. ! 217: */ ! 218: ! 219: kern_return_t ! 220: ipc_object_alloc( ! 221: ipc_space_t space, ! 222: ipc_object_type_t otype, ! 223: mach_port_type_t type, ! 224: mach_port_urefs_t urefs, ! 225: mach_port_t *namep, ! 226: ipc_object_t *objectp) ! 227: { ! 228: ipc_object_t object; ! 229: ipc_entry_t entry; ! 230: kern_return_t kr; ! 231: ! 232: assert(otype < IOT_NUMBER); ! 233: assert((type & MACH_PORT_TYPE_ALL_RIGHTS) == type); ! 234: assert(type != MACH_PORT_TYPE_NONE); ! 235: assert(urefs <= MACH_PORT_UREFS_MAX); ! 236: ! 237: object = io_alloc(otype); ! 238: if (object == IO_NULL) ! 239: return KERN_RESOURCE_SHORTAGE; ! 240: ! 241: if (otype == IOT_PORT) { ! 242: ipc_port_t port = (ipc_port_t)object; ! 243: ! 244: bzero((char *)port, sizeof(*port)); ! 245: } else if (otype == IOT_PORT_SET) { ! 246: ipc_pset_t pset = (ipc_pset_t)object; ! 247: ! 248: bzero((char *)pset, sizeof(*pset)); ! 249: } ! 250: *namep = (mach_port_t)object; ! 251: kr = ipc_entry_alloc(space, namep, &entry); ! 252: if (kr != KERN_SUCCESS) { ! 253: io_free(otype, object); ! 254: return kr; ! 255: } ! 256: /* space is write-locked */ ! 257: ! 258: entry->ie_bits |= type | urefs; ! 259: entry->ie_object = object; ! 260: ! 261: io_lock_init(object); ! 262: io_lock(object); ! 263: is_write_unlock(space); ! 264: ! 265: object->io_references = 1; /* for entry, not caller */ ! 266: object->io_bits = io_makebits(TRUE, otype, 0); ! 267: ! 268: *objectp = object; ! 269: return KERN_SUCCESS; ! 270: } ! 271: ! 272: /* ! 273: * Routine: ipc_object_alloc_name ! 274: * Purpose: ! 275: * Allocate an object, with a specific name. ! 276: * Conditions: ! 277: * Nothing locked. If successful, the object is returned locked. ! 278: * The caller doesn't get a reference for the object. ! 279: * Returns: ! 280: * KERN_SUCCESS The object is allocated. ! 281: * KERN_INVALID_TASK The space is dead. ! 282: * KERN_NAME_EXISTS The name already denotes a right. ! 283: * KERN_RESOURCE_SHORTAGE Couldn't allocate memory. ! 284: */ ! 285: ! 286: kern_return_t ! 287: ipc_object_alloc_name( ! 288: ipc_space_t space, ! 289: ipc_object_type_t otype, ! 290: mach_port_type_t type, ! 291: mach_port_urefs_t urefs, ! 292: mach_port_t name, ! 293: ipc_object_t *objectp) ! 294: { ! 295: ipc_object_t object; ! 296: ipc_entry_t entry; ! 297: kern_return_t kr; ! 298: ! 299: assert(otype < IOT_NUMBER); ! 300: assert((type & MACH_PORT_TYPE_ALL_RIGHTS) == type); ! 301: assert(type != MACH_PORT_TYPE_NONE); ! 302: assert(urefs <= MACH_PORT_UREFS_MAX); ! 303: ! 304: object = io_alloc(otype); ! 305: if (object == IO_NULL) ! 306: return KERN_RESOURCE_SHORTAGE; ! 307: ! 308: if (otype == IOT_PORT) { ! 309: ipc_port_t port = (ipc_port_t)object; ! 310: ! 311: bzero((char *)port, sizeof(*port)); ! 312: } else if (otype == IOT_PORT_SET) { ! 313: ipc_pset_t pset = (ipc_pset_t)object; ! 314: ! 315: bzero((char *)pset, sizeof(*pset)); ! 316: } ! 317: ! 318: kr = ipc_entry_alloc_name(space, name, &entry); ! 319: if (kr != KERN_SUCCESS) { ! 320: io_free(otype, object); ! 321: return kr; ! 322: } ! 323: /* space is write-locked */ ! 324: ! 325: if (ipc_right_inuse(space, name, entry)) { ! 326: io_free(otype, object); ! 327: return KERN_NAME_EXISTS; ! 328: } ! 329: ! 330: entry->ie_bits |= type | urefs; ! 331: entry->ie_object = object; ! 332: ! 333: io_lock_init(object); ! 334: io_lock(object); ! 335: is_write_unlock(space); ! 336: ! 337: object->io_references = 1; /* for entry, not caller */ ! 338: object->io_bits = io_makebits(TRUE, otype, 0); ! 339: ! 340: *objectp = object; ! 341: return KERN_SUCCESS; ! 342: } ! 343: ! 344: /* ! 345: * Routine: ipc_object_copyin_type ! 346: * Purpose: ! 347: * Convert a send type name to a received type name. ! 348: */ ! 349: ! 350: mach_msg_type_name_t ! 351: ipc_object_copyin_type( ! 352: mach_msg_type_name_t msgt_name) ! 353: { ! 354: switch (msgt_name) { ! 355: case 0: ! 356: return 0; ! 357: ! 358: case MACH_MSG_TYPE_MOVE_RECEIVE: ! 359: return MACH_MSG_TYPE_PORT_RECEIVE; ! 360: ! 361: case MACH_MSG_TYPE_MOVE_SEND_ONCE: ! 362: case MACH_MSG_TYPE_MAKE_SEND_ONCE: ! 363: return MACH_MSG_TYPE_PORT_SEND_ONCE; ! 364: ! 365: case MACH_MSG_TYPE_MOVE_SEND: ! 366: case MACH_MSG_TYPE_MAKE_SEND: ! 367: case MACH_MSG_TYPE_COPY_SEND: ! 368: return MACH_MSG_TYPE_PORT_SEND; ! 369: ! 370: #if MACH_IPC_COMPAT ! 371: case MSG_TYPE_PORT: ! 372: return MACH_MSG_TYPE_PORT_SEND; ! 373: ! 374: case MSG_TYPE_PORT_ALL: ! 375: return MACH_MSG_TYPE_PORT_RECEIVE; ! 376: #endif MACH_IPC_COMPAT ! 377: ! 378: default: ! 379: #if MACH_ASSERT ! 380: assert(!"ipc_object_copyin_type: strange rights"); ! 381: #else ! 382: panic("ipc_object_copyin_type: strange rights"); ! 383: #endif ! 384: return 0; /* in case assert/panic returns */ ! 385: } ! 386: } ! 387: ! 388: /* ! 389: * Routine: ipc_object_copyin ! 390: * Purpose: ! 391: * Copyin a capability from a space. ! 392: * If successful, the caller gets a ref ! 393: * for the resulting object, unless it is IO_DEAD. ! 394: * Conditions: ! 395: * Nothing locked. ! 396: * Returns: ! 397: * KERN_SUCCESS Acquired an object, possibly IO_DEAD. ! 398: * KERN_INVALID_TASK The space is dead. ! 399: * KERN_INVALID_NAME Name doesn't exist in space. ! 400: * KERN_INVALID_RIGHT Name doesn't denote correct right. ! 401: */ ! 402: ! 403: kern_return_t ! 404: ipc_object_copyin( ! 405: ipc_space_t space, ! 406: mach_port_t name, ! 407: mach_msg_type_name_t msgt_name, ! 408: ipc_object_t *objectp) ! 409: { ! 410: ipc_entry_t entry; ! 411: ipc_port_t soright; ! 412: kern_return_t kr; ! 413: ! 414: /* ! 415: * Could first try a read lock when doing ! 416: * MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND, ! 417: * and MACH_MSG_TYPE_MAKE_SEND_ONCE. ! 418: */ ! 419: ! 420: kr = ipc_right_lookup_write(space, name, &entry); ! 421: if (kr != KERN_SUCCESS) ! 422: return kr; ! 423: /* space is write-locked and active */ ! 424: ! 425: kr = ipc_right_copyin(space, name, entry, ! 426: msgt_name, TRUE, ! 427: objectp, &soright); ! 428: if (IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE) ! 429: ipc_entry_dealloc(space, name, entry); ! 430: is_write_unlock(space); ! 431: ! 432: if ((kr == KERN_SUCCESS) && (soright != IP_NULL)) ! 433: ipc_notify_port_deleted(soright, name); ! 434: ! 435: return kr; ! 436: } ! 437: ! 438: /* ! 439: * Routine: ipc_object_copyin_from_kernel ! 440: * Purpose: ! 441: * Copyin a naked capability from the kernel. ! 442: * ! 443: * MACH_MSG_TYPE_MOVE_RECEIVE ! 444: * The receiver must be ipc_space_kernel. ! 445: * Consumes the naked receive right. ! 446: * MACH_MSG_TYPE_COPY_SEND ! 447: * A naked send right must be supplied. ! 448: * The port gains a reference, and a send right ! 449: * if the port is still active. ! 450: * MACH_MSG_TYPE_MAKE_SEND ! 451: * The receiver must be ipc_space_kernel. ! 452: * The port gains a reference and a send right. ! 453: * MACH_MSG_TYPE_MOVE_SEND ! 454: * Consumes a naked send right. ! 455: * MACH_MSG_TYPE_MAKE_SEND_ONCE ! 456: * The receiver must be ipc_space_kernel. ! 457: * The port gains a reference and a send-once right. ! 458: * MACH_MSG_TYPE_MOVE_SEND_ONCE ! 459: * Consumes a naked send-once right. ! 460: * Conditions: ! 461: * Nothing locked. ! 462: */ ! 463: ! 464: void ! 465: ipc_object_copyin_from_kernel( ! 466: ipc_object_t object, ! 467: mach_msg_type_name_t msgt_name) ! 468: { ! 469: assert(IO_VALID(object)); ! 470: ! 471: switch (msgt_name) { ! 472: case MACH_MSG_TYPE_MOVE_RECEIVE: { ! 473: ipc_port_t port = (ipc_port_t) object; ! 474: ! 475: ip_lock(port); ! 476: assert(ip_active(port)); ! 477: assert(port->ip_receiver_name != MACH_PORT_NULL); ! 478: assert(port->ip_receiver == ipc_space_kernel); ! 479: ! 480: /* relevant part of ipc_port_clear_receiver */ ! 481: ipc_port_set_mscount(port, 0); ! 482: ! 483: port->ip_receiver_name = MACH_PORT_NULL; ! 484: port->ip_destination = IP_NULL; ! 485: ip_unlock(port); ! 486: break; ! 487: } ! 488: ! 489: case MACH_MSG_TYPE_COPY_SEND: { ! 490: ipc_port_t port = (ipc_port_t) object; ! 491: ! 492: ip_lock(port); ! 493: if (ip_active(port)) { ! 494: assert(port->ip_srights > 0); ! 495: port->ip_srights++; ! 496: } ! 497: ip_reference(port); ! 498: ip_unlock(port); ! 499: break; ! 500: } ! 501: ! 502: case MACH_MSG_TYPE_MAKE_SEND: { ! 503: ipc_port_t port = (ipc_port_t) object; ! 504: ! 505: ip_lock(port); ! 506: assert(ip_active(port)); ! 507: assert(port->ip_receiver_name != MACH_PORT_NULL); ! 508: assert(port->ip_receiver == ipc_space_kernel); ! 509: ! 510: ip_reference(port); ! 511: port->ip_mscount++; ! 512: port->ip_srights++; ! 513: ip_unlock(port); ! 514: break; ! 515: } ! 516: ! 517: case MACH_MSG_TYPE_MOVE_SEND: ! 518: /* move naked send right into the message */ ! 519: break; ! 520: ! 521: case MACH_MSG_TYPE_MAKE_SEND_ONCE: { ! 522: ipc_port_t port = (ipc_port_t) object; ! 523: ! 524: ip_lock(port); ! 525: assert(ip_active(port)); ! 526: assert(port->ip_receiver_name != MACH_PORT_NULL); ! 527: assert(port->ip_receiver == ipc_space_kernel); ! 528: ! 529: ip_reference(port); ! 530: port->ip_sorights++; ! 531: ip_unlock(port); ! 532: break; ! 533: } ! 534: ! 535: case MACH_MSG_TYPE_MOVE_SEND_ONCE: ! 536: /* move naked send-once right into the message */ ! 537: break; ! 538: ! 539: default: ! 540: #if MACH_ASSERT ! 541: assert(!"ipc_object_copyin_from_kernel: strange rights"); ! 542: #else ! 543: panic("ipc_object_copyin_from_kernel: strange rights"); ! 544: #endif ! 545: } ! 546: } ! 547: ! 548: /* ! 549: * Routine: ipc_object_destroy ! 550: * Purpose: ! 551: * Destroys a naked capability. ! 552: * Consumes a ref for the object. ! 553: * ! 554: * A receive right should be in limbo or in transit. ! 555: * Conditions: ! 556: * Nothing locked. ! 557: */ ! 558: ! 559: void ! 560: ipc_object_destroy( ! 561: ipc_object_t object, ! 562: mach_msg_type_name_t msgt_name) ! 563: { ! 564: assert(IO_VALID(object)); ! 565: assert(io_otype(object) == IOT_PORT); ! 566: ! 567: switch (msgt_name) { ! 568: case MACH_MSG_TYPE_PORT_SEND: ! 569: ipc_port_release_send((ipc_port_t) object); ! 570: break; ! 571: ! 572: case MACH_MSG_TYPE_PORT_SEND_ONCE: ! 573: ipc_notify_send_once((ipc_port_t) object); ! 574: break; ! 575: ! 576: case MACH_MSG_TYPE_PORT_RECEIVE: ! 577: ipc_port_release_receive((ipc_port_t) object); ! 578: break; ! 579: ! 580: default: ! 581: panic("ipc_object_destroy: strange rights"); ! 582: } ! 583: } ! 584: ! 585: /* ! 586: * Routine: ipc_object_copyout ! 587: * Purpose: ! 588: * Copyout a capability, placing it into a space. ! 589: * If successful, consumes a ref for the object. ! 590: * Conditions: ! 591: * Nothing locked. ! 592: * Returns: ! 593: * KERN_SUCCESS Copied out object, consumed ref. ! 594: * KERN_INVALID_TASK The space is dead. ! 595: * KERN_INVALID_CAPABILITY The object is dead. ! 596: * KERN_NO_SPACE No room in space for another right. ! 597: * KERN_RESOURCE_SHORTAGE No memory available. ! 598: * KERN_UREFS_OVERFLOW Urefs limit exceeded ! 599: * and overflow wasn't specified. ! 600: */ ! 601: ! 602: kern_return_t ! 603: ipc_object_copyout( ! 604: ipc_space_t space, ! 605: ipc_object_t object, ! 606: mach_msg_type_name_t msgt_name, ! 607: boolean_t overflow, ! 608: mach_port_t *namep) ! 609: { ! 610: mach_port_t name; ! 611: ipc_entry_t entry; ! 612: kern_return_t kr; ! 613: ! 614: assert(IO_VALID(object)); ! 615: assert(io_otype(object) == IOT_PORT); ! 616: ! 617: is_write_lock(space); ! 618: ! 619: for (;;) { ! 620: if (!space->is_active) { ! 621: is_write_unlock(space); ! 622: return KERN_INVALID_TASK; ! 623: } ! 624: ! 625: if ((msgt_name != MACH_MSG_TYPE_PORT_SEND_ONCE) && ! 626: ipc_right_reverse(space, object, &name, &entry)) { ! 627: /* object is locked and active */ ! 628: ! 629: assert(entry->ie_bits & MACH_PORT_TYPE_SEND_RECEIVE); ! 630: break; ! 631: } ! 632: ! 633: kr = ipc_entry_get(space, &name, &entry); ! 634: if (kr != KERN_SUCCESS) { ! 635: /* unlocks/locks space, so must start again */ ! 636: ! 637: kr = ipc_entry_grow_table(space); ! 638: if (kr != KERN_SUCCESS) ! 639: return kr; /* space is unlocked */ ! 640: ! 641: continue; ! 642: } ! 643: ! 644: assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE); ! 645: assert(entry->ie_object == IO_NULL); ! 646: ! 647: io_lock(object); ! 648: if (!io_active(object)) { ! 649: io_unlock(object); ! 650: ipc_entry_dealloc(space, name, entry); ! 651: is_write_unlock(space); ! 652: return KERN_INVALID_CAPABILITY; ! 653: } ! 654: ! 655: entry->ie_object = object; ! 656: break; ! 657: } ! 658: ! 659: /* space is write-locked and active, object is locked and active */ ! 660: ! 661: kr = ipc_right_copyout(space, name, entry, ! 662: msgt_name, overflow, object); ! 663: /* object is unlocked */ ! 664: is_write_unlock(space); ! 665: ! 666: if (kr == KERN_SUCCESS) ! 667: *namep = name; ! 668: return kr; ! 669: } ! 670: ! 671: #if 0 ! 672: /* XXX same, but don't check for already-existing send rights */ ! 673: kern_return_t ! 674: ipc_object_copyout_multiname(space, object, namep) ! 675: ipc_space_t space; ! 676: ipc_object_t object; ! 677: mach_port_t *namep; ! 678: { ! 679: mach_port_t name; ! 680: ipc_entry_t entry; ! 681: kern_return_t kr; ! 682: ! 683: assert(IO_VALID(object)); ! 684: assert(io_otype(object) == IOT_PORT); ! 685: ! 686: is_write_lock(space); ! 687: ! 688: for (;;) { ! 689: if (!space->is_active) { ! 690: is_write_unlock(space); ! 691: return KERN_INVALID_TASK; ! 692: } ! 693: ! 694: kr = ipc_entry_get(space, &name, &entry); ! 695: if (kr != KERN_SUCCESS) { ! 696: /* unlocks/locks space, so must start again */ ! 697: ! 698: kr = ipc_entry_grow_table(space); ! 699: if (kr != KERN_SUCCESS) ! 700: return kr; /* space is unlocked */ ! 701: ! 702: continue; ! 703: } ! 704: ! 705: assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE); ! 706: assert(entry->ie_object == IO_NULL); ! 707: ! 708: io_lock(object); ! 709: if (!io_active(object)) { ! 710: io_unlock(object); ! 711: ipc_entry_dealloc(space, name, entry); ! 712: is_write_unlock(space); ! 713: return KERN_INVALID_CAPABILITY; ! 714: } ! 715: ! 716: entry->ie_object = object; ! 717: break; ! 718: } ! 719: ! 720: /* space is write-locked and active, object is locked and active */ ! 721: ! 722: kr = ipc_right_copyout_multiname(space, name, entry, object); ! 723: /* object is unlocked */ ! 724: is_write_unlock(space); ! 725: ! 726: if (kr == KERN_SUCCESS) ! 727: *namep = name; ! 728: return kr; ! 729: } ! 730: #endif 0 ! 731: ! 732: /* ! 733: * Routine: ipc_object_copyout_name ! 734: * Purpose: ! 735: * Copyout a capability, placing it into a space. ! 736: * The specified name is used for the capability. ! 737: * If successful, consumes a ref for the object. ! 738: * Conditions: ! 739: * Nothing locked. ! 740: * Returns: ! 741: * KERN_SUCCESS Copied out object, consumed ref. ! 742: * KERN_INVALID_TASK The space is dead. ! 743: * KERN_INVALID_CAPABILITY The object is dead. ! 744: * KERN_RESOURCE_SHORTAGE No memory available. ! 745: * KERN_UREFS_OVERFLOW Urefs limit exceeded ! 746: * and overflow wasn't specified. ! 747: * KERN_RIGHT_EXISTS Space has rights under another name. ! 748: * KERN_NAME_EXISTS Name is already used. ! 749: */ ! 750: ! 751: kern_return_t ! 752: ipc_object_copyout_name( ! 753: ipc_space_t space, ! 754: ipc_object_t object, ! 755: mach_msg_type_name_t msgt_name, ! 756: boolean_t overflow, ! 757: mach_port_t name) ! 758: { ! 759: mach_port_t oname; ! 760: ipc_entry_t oentry; ! 761: ipc_entry_t entry; ! 762: kern_return_t kr; ! 763: ! 764: assert(IO_VALID(object)); ! 765: assert(io_otype(object) == IOT_PORT); ! 766: ! 767: kr = ipc_entry_alloc_name(space, name, &entry); ! 768: if (kr != KERN_SUCCESS) ! 769: return kr; ! 770: /* space is write-locked and active */ ! 771: ! 772: if ((msgt_name != MACH_MSG_TYPE_PORT_SEND_ONCE) && ! 773: ipc_right_reverse(space, object, &oname, &oentry)) { ! 774: /* object is locked and active */ ! 775: ! 776: if (name != oname) { ! 777: io_unlock(object); ! 778: ! 779: if (IE_BITS_TYPE(entry->ie_bits) ! 780: == MACH_PORT_TYPE_NONE) ! 781: ipc_entry_dealloc(space, name, entry); ! 782: ! 783: is_write_unlock(space); ! 784: return KERN_RIGHT_EXISTS; ! 785: } ! 786: ! 787: assert(entry == oentry); ! 788: assert(entry->ie_bits & MACH_PORT_TYPE_SEND_RECEIVE); ! 789: } else { ! 790: if (ipc_right_inuse(space, name, entry)) ! 791: return KERN_NAME_EXISTS; ! 792: ! 793: assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE); ! 794: assert(entry->ie_object == IO_NULL); ! 795: ! 796: io_lock(object); ! 797: if (!io_active(object)) { ! 798: io_unlock(object); ! 799: ipc_entry_dealloc(space, name, entry); ! 800: is_write_unlock(space); ! 801: return KERN_INVALID_CAPABILITY; ! 802: } ! 803: ! 804: entry->ie_object = object; ! 805: } ! 806: ! 807: /* space is write-locked and active, object is locked and active */ ! 808: ! 809: kr = ipc_right_copyout(space, name, entry, ! 810: msgt_name, overflow, object); ! 811: /* object is unlocked */ ! 812: is_write_unlock(space); ! 813: return kr; ! 814: } ! 815: ! 816: /* ! 817: * Routine: ipc_object_copyout_dest ! 818: * Purpose: ! 819: * Translates/consumes the destination right of a message. ! 820: * This is unlike normal copyout because the right is consumed ! 821: * in a funny way instead of being given to the receiving space. ! 822: * The receiver gets his name for the port, if he has receive ! 823: * rights, otherwise MACH_PORT_NULL. ! 824: * Conditions: ! 825: * The object is locked and active. Nothing else locked. ! 826: * The object is unlocked and loses a reference. ! 827: */ ! 828: ! 829: void ! 830: ipc_object_copyout_dest( ! 831: ipc_space_t space, ! 832: ipc_object_t object, ! 833: mach_msg_type_name_t msgt_name, ! 834: mach_port_t *namep) ! 835: { ! 836: mach_port_t name; ! 837: ! 838: assert(IO_VALID(object)); ! 839: assert(io_active(object)); ! 840: ! 841: io_release(object); ! 842: ! 843: /* ! 844: * If the space is the receiver/owner of the object, ! 845: * then we quietly consume the right and return ! 846: * the space's name for the object. Otherwise ! 847: * we destroy the right and return MACH_PORT_NULL. ! 848: */ ! 849: ! 850: switch (msgt_name) { ! 851: case MACH_MSG_TYPE_PORT_SEND: { ! 852: ipc_port_t port = (ipc_port_t) object; ! 853: ipc_port_t nsrequest = IP_NULL; ! 854: mach_port_mscount_t mscount = 0; /* '=0' to shut up lint */ ! 855: ! 856: assert(port->ip_srights > 0); ! 857: if (--port->ip_srights == 0) { ! 858: nsrequest = port->ip_nsrequest; ! 859: if (nsrequest != IP_NULL) { ! 860: port->ip_nsrequest = IP_NULL; ! 861: mscount = port->ip_mscount; ! 862: } ! 863: } ! 864: ! 865: if (port->ip_receiver == space) ! 866: name = port->ip_receiver_name; ! 867: else ! 868: name = MACH_PORT_NULL; ! 869: ! 870: ip_unlock(port); ! 871: ! 872: if (nsrequest != IP_NULL) ! 873: ipc_notify_no_senders(nsrequest, mscount); ! 874: ! 875: break; ! 876: } ! 877: ! 878: case MACH_MSG_TYPE_PORT_SEND_ONCE: { ! 879: ipc_port_t port = (ipc_port_t) object; ! 880: ! 881: assert(port->ip_sorights > 0); ! 882: ! 883: if (port->ip_receiver == space) { ! 884: /* quietly consume the send-once right */ ! 885: ! 886: port->ip_sorights--; ! 887: name = port->ip_receiver_name; ! 888: ip_unlock(port); ! 889: } else { ! 890: /* ! 891: * A very bizarre case. The message ! 892: * was received, but before this copyout ! 893: * happened the space lost receive rights. ! 894: * We can't quietly consume the soright ! 895: * out from underneath some other task, ! 896: * so generate a send-once notification. ! 897: */ ! 898: ! 899: ip_reference(port); /* restore ref */ ! 900: ip_unlock(port); ! 901: ! 902: ipc_notify_send_once(port); ! 903: name = MACH_PORT_NULL; ! 904: } ! 905: ! 906: break; ! 907: } ! 908: ! 909: default: ! 910: #if MACH_ASSERT ! 911: assert(!"ipc_object_copyout_dest: strange rights"); ! 912: #else ! 913: panic("ipc_object_copyout_dest: strange rights"); ! 914: #endif ! 915: ! 916: } ! 917: ! 918: *namep = name; ! 919: } ! 920: ! 921: /* ! 922: * Routine: ipc_object_rename ! 923: * Purpose: ! 924: * Rename an entry in a space. ! 925: * Conditions: ! 926: * Nothing locked. ! 927: * Returns: ! 928: * KERN_SUCCESS Renamed the entry. ! 929: * KERN_INVALID_TASK The space was dead. ! 930: * KERN_INVALID_NAME oname didn't denote an entry. ! 931: * KERN_NAME_EXISTS nname already denoted an entry. ! 932: * KERN_RESOURCE_SHORTAGE Couldn't allocate new entry. ! 933: */ ! 934: ! 935: kern_return_t ! 936: ipc_object_rename( ! 937: ipc_space_t space, ! 938: mach_port_t oname, ! 939: mach_port_t nname) ! 940: { ! 941: ipc_entry_t oentry, nentry; ! 942: kern_return_t kr; ! 943: ! 944: kr = ipc_entry_alloc_name(space, nname, &nentry); ! 945: if (kr != KERN_SUCCESS) ! 946: return kr; ! 947: /* space is write-locked and active */ ! 948: ! 949: if (ipc_right_inuse(space, nname, nentry)) { ! 950: /* space is unlocked */ ! 951: return KERN_NAME_EXISTS; ! 952: } ! 953: ! 954: /* don't let ipc_entry_lookup see the uninitialized new entry */ ! 955: ! 956: if ((oname == nname) || ! 957: ((oentry = ipc_entry_lookup(space, oname)) == IE_NULL)) { ! 958: ipc_entry_dealloc(space, nname, nentry); ! 959: is_write_unlock(space); ! 960: return KERN_INVALID_NAME; ! 961: } ! 962: ! 963: kr = ipc_right_rename(space, oname, oentry, nname, nentry); ! 964: /* space is unlocked */ ! 965: return kr; ! 966: } ! 967: ! 968: #if MACH_IPC_COMPAT ! 969: ! 970: /* ! 971: * Routine: ipc_object_copyout_type_compat ! 972: * Purpose: ! 973: * Convert a carried type name to an old type name. ! 974: */ ! 975: ! 976: mach_msg_type_name_t ! 977: ipc_object_copyout_type_compat(msgt_name) ! 978: mach_msg_type_name_t msgt_name; ! 979: { ! 980: switch (msgt_name) { ! 981: case MACH_MSG_TYPE_PORT_SEND: ! 982: case MACH_MSG_TYPE_PORT_SEND_ONCE: ! 983: return MSG_TYPE_PORT; ! 984: ! 985: case MACH_MSG_TYPE_PORT_RECEIVE: ! 986: return MSG_TYPE_PORT_ALL; ! 987: ! 988: default: ! 989: #if MACH_ASSERT ! 990: assert(!"ipc_object_copyout_type_compat: strange rights"); ! 991: #else ! 992: panic("ipc_object_copyout_type_compat: strange rights"); ! 993: #endif ! 994: } ! 995: } ! 996: ! 997: /* ! 998: * Routine: ipc_object_copyin_compat ! 999: * Purpose: ! 1000: * Copyin a capability from a space. ! 1001: * If successful, the caller gets a ref ! 1002: * for the resulting object, which is always valid. ! 1003: * Conditions: ! 1004: * Nothing locked. ! 1005: * Returns: ! 1006: * KERN_SUCCESS Acquired a valid object. ! 1007: * KERN_INVALID_TASK The space is dead. ! 1008: * KERN_INVALID_NAME Name doesn't exist in space. ! 1009: * KERN_INVALID_RIGHT Name doesn't denote correct right. ! 1010: */ ! 1011: ! 1012: kern_return_t ! 1013: ipc_object_copyin_compat(space, name, msgt_name, dealloc, objectp) ! 1014: ipc_space_t space; ! 1015: mach_port_t name; ! 1016: mach_msg_type_name_t msgt_name; ! 1017: boolean_t dealloc; ! 1018: ipc_object_t *objectp; ! 1019: { ! 1020: ipc_entry_t entry; ! 1021: kern_return_t kr; ! 1022: ! 1023: kr = ipc_right_lookup_write(space, name, &entry); ! 1024: if (kr != KERN_SUCCESS) ! 1025: return kr; ! 1026: /* space is write-locked and active */ ! 1027: ! 1028: kr = ipc_right_copyin_compat(space, name, entry, ! 1029: msgt_name, dealloc, objectp); ! 1030: /* space is unlocked */ ! 1031: return kr; ! 1032: } ! 1033: ! 1034: /* ! 1035: * Routine: ipc_object_copyin_header ! 1036: * Purpose: ! 1037: * Copyin a capability from a space. ! 1038: * If successful, the caller gets a ref ! 1039: * for the resulting object, which is always valid. ! 1040: * The type of the acquired capability is returned. ! 1041: * Conditions: ! 1042: * Nothing locked. ! 1043: * Returns: ! 1044: * KERN_SUCCESS Acquired a valid object. ! 1045: * KERN_INVALID_TASK The space is dead. ! 1046: * KERN_INVALID_NAME Name doesn't exist in space. ! 1047: * KERN_INVALID_RIGHT Name doesn't denote correct right. ! 1048: */ ! 1049: ! 1050: kern_return_t ! 1051: ipc_object_copyin_header(space, name, objectp, msgt_namep) ! 1052: ipc_space_t space; ! 1053: mach_port_t name; ! 1054: ipc_object_t *objectp; ! 1055: mach_msg_type_name_t *msgt_namep; ! 1056: { ! 1057: ipc_entry_t entry; ! 1058: kern_return_t kr; ! 1059: ! 1060: kr = ipc_right_lookup_write(space, name, &entry); ! 1061: if (kr != KERN_SUCCESS) ! 1062: return kr; ! 1063: /* space is write-locked and active */ ! 1064: ! 1065: kr = ipc_right_copyin_header(space, name, entry, ! 1066: objectp, msgt_namep); ! 1067: /* space is unlocked */ ! 1068: return kr; ! 1069: } ! 1070: ! 1071: /* ! 1072: * Routine: ipc_object_copyout_compat ! 1073: * Purpose: ! 1074: * Copyout a capability, placing it into a space. ! 1075: * If successful, consumes a ref for the object. ! 1076: * ! 1077: * Marks new entries with IE_BITS_COMPAT. ! 1078: * Conditions: ! 1079: * Nothing locked. ! 1080: * Returns: ! 1081: * KERN_SUCCESS Copied out object, consumed ref. ! 1082: * KERN_INVALID_TASK The space is dead. ! 1083: * KERN_INVALID_CAPABILITY The object is dead. ! 1084: * KERN_NO_SPACE No room in space for another right. ! 1085: * KERN_RESOURCE_SHORTAGE No memory available. ! 1086: */ ! 1087: ! 1088: kern_return_t ! 1089: ipc_object_copyout_compat(space, object, msgt_name, namep) ! 1090: ipc_space_t space; ! 1091: ipc_object_t object; ! 1092: mach_msg_type_name_t msgt_name; ! 1093: mach_port_t *namep; ! 1094: { ! 1095: mach_port_t name; ! 1096: ipc_entry_t entry; ! 1097: ipc_port_t port; ! 1098: kern_return_t kr; ! 1099: ! 1100: assert(IO_VALID(object)); ! 1101: assert(io_otype(object) == IOT_PORT); ! 1102: port = (ipc_port_t) object; ! 1103: ! 1104: is_write_lock(space); ! 1105: ! 1106: for (;;) { ! 1107: ipc_port_request_index_t request; ! 1108: ! 1109: if (!space->is_active) { ! 1110: is_write_unlock(space); ! 1111: return KERN_INVALID_TASK; ! 1112: } ! 1113: ! 1114: if ((msgt_name != MACH_MSG_TYPE_PORT_SEND_ONCE) && ! 1115: ipc_right_reverse(space, (ipc_object_t) port, ! 1116: &name, &entry)) { ! 1117: /* port is locked and active */ ! 1118: ! 1119: assert(entry->ie_bits & MACH_PORT_TYPE_SEND_RECEIVE); ! 1120: break; ! 1121: } ! 1122: ! 1123: kr = ipc_entry_get(space, &name, &entry); ! 1124: if (kr != KERN_SUCCESS) { ! 1125: /* unlocks/locks space, so must start again */ ! 1126: ! 1127: kr = ipc_entry_grow_table(space); ! 1128: if (kr != KERN_SUCCESS) ! 1129: return kr; /* space is unlocked */ ! 1130: ! 1131: continue; ! 1132: } ! 1133: ! 1134: assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE); ! 1135: assert(entry->ie_object == IO_NULL); ! 1136: ! 1137: ip_lock(port); ! 1138: if (!ip_active(port)) { ! 1139: ip_unlock(port); ! 1140: ipc_entry_dealloc(space, name, entry); ! 1141: is_write_unlock(space); ! 1142: return KERN_INVALID_CAPABILITY; ! 1143: } ! 1144: ! 1145: kr = ipc_port_dnrequest(port, name, ipr_spacem(space), ! 1146: &request); ! 1147: if (kr != KERN_SUCCESS) { ! 1148: ipc_entry_dealloc(space, name, entry); ! 1149: is_write_unlock(space); ! 1150: ! 1151: kr = ipc_port_dngrow(port); ! 1152: /* port is unlocked */ ! 1153: if (kr != KERN_SUCCESS) ! 1154: return kr; ! 1155: ! 1156: is_write_lock(space); ! 1157: continue; ! 1158: } ! 1159: ! 1160: is_reference(space); /* for dnrequest */ ! 1161: entry->ie_object = (ipc_object_t) port; ! 1162: entry->ie_request = request; ! 1163: entry->ie_bits |= IE_BITS_COMPAT; ! 1164: break; ! 1165: } ! 1166: ! 1167: /* space is write-locked and active, port is locked and active */ ! 1168: ! 1169: kr = ipc_right_copyout(space, name, entry, ! 1170: msgt_name, TRUE, (ipc_object_t) port); ! 1171: /* object is unlocked */ ! 1172: is_write_unlock(space); ! 1173: ! 1174: if (kr == KERN_SUCCESS) ! 1175: *namep = name; ! 1176: return kr; ! 1177: } ! 1178: ! 1179: /* ! 1180: * Routine: ipc_object_copyout_name_compat ! 1181: * Purpose: ! 1182: * Copyout a capability, placing it into a space. ! 1183: * The specified name is used for the capability. ! 1184: * If successful, consumes a ref for the object. ! 1185: * ! 1186: * Like ipc_object_copyout_name, except that ! 1187: * the name can't be in use at all, even for the same ! 1188: * port, and IE_BITS_COMPAT gets turned on. ! 1189: * Conditions: ! 1190: * Nothing locked. ! 1191: * Returns: ! 1192: * KERN_SUCCESS Copied out object, consumed ref. ! 1193: * KERN_INVALID_TASK The space is dead. ! 1194: * KERN_INVALID_CAPABILITY The object is dead. ! 1195: * KERN_RESOURCE_SHORTAGE No memory available. ! 1196: * KERN_RIGHT_EXISTS Space has rights under another name. ! 1197: * KERN_NAME_EXISTS Name is already used. ! 1198: */ ! 1199: ! 1200: kern_return_t ! 1201: ipc_object_copyout_name_compat(space, object, msgt_name, name) ! 1202: ipc_space_t space; ! 1203: ipc_object_t object; ! 1204: mach_msg_type_name_t msgt_name; ! 1205: mach_port_t name; ! 1206: { ! 1207: ipc_entry_t entry; ! 1208: ipc_port_t port; ! 1209: kern_return_t kr; ! 1210: ! 1211: assert(IO_VALID(object)); ! 1212: assert(io_otype(object) == IOT_PORT); ! 1213: port = (ipc_port_t) object; ! 1214: ! 1215: for (;;) { ! 1216: mach_port_t oname; ! 1217: ipc_entry_t oentry; ! 1218: ipc_port_request_index_t request; ! 1219: ! 1220: kr = ipc_entry_alloc_name(space, name, &entry); ! 1221: if (kr != KERN_SUCCESS) ! 1222: return kr; ! 1223: /* space is write-locked and active */ ! 1224: ! 1225: if (ipc_right_inuse(space, name, entry)) ! 1226: return KERN_NAME_EXISTS; /* space is unlocked */ ! 1227: ! 1228: assert(IE_BITS_TYPE(entry->ie_bits) == MACH_PORT_TYPE_NONE); ! 1229: assert(entry->ie_object == IO_NULL); ! 1230: ! 1231: if ((msgt_name != MACH_MSG_TYPE_PORT_SEND_ONCE) && ! 1232: ipc_right_reverse(space, (ipc_object_t) port, ! 1233: &oname, &oentry)) { ! 1234: /* port is locked and active */ ! 1235: ! 1236: ip_unlock(port); ! 1237: ipc_entry_dealloc(space, name, entry); ! 1238: is_write_unlock(space); ! 1239: return KERN_RIGHT_EXISTS; ! 1240: } ! 1241: ! 1242: ip_lock(port); ! 1243: if (!ip_active(port)) { ! 1244: ip_unlock(port); ! 1245: ipc_entry_dealloc(space, name, entry); ! 1246: is_write_unlock(space); ! 1247: return KERN_INVALID_CAPABILITY; ! 1248: } ! 1249: ! 1250: kr = ipc_port_dnrequest(port, name, ipr_spacem(space), ! 1251: &request); ! 1252: if (kr != KERN_SUCCESS) { ! 1253: ipc_entry_dealloc(space, name, entry); ! 1254: is_write_unlock(space); ! 1255: ! 1256: kr = ipc_port_dngrow(port); ! 1257: /* port is unlocked */ ! 1258: if (kr != KERN_SUCCESS) ! 1259: return kr; ! 1260: ! 1261: continue; ! 1262: } ! 1263: ! 1264: is_reference(space); /* for dnrequest */ ! 1265: entry->ie_object = (ipc_object_t) port; ! 1266: entry->ie_request = request; ! 1267: entry->ie_bits |= IE_BITS_COMPAT; ! 1268: break; ! 1269: } ! 1270: ! 1271: /* space is write-locked and active, port is locked and active */ ! 1272: ! 1273: kr = ipc_right_copyout(space, name, entry, ! 1274: msgt_name, TRUE, (ipc_object_t) port); ! 1275: /* object is unlocked */ ! 1276: is_write_unlock(space); ! 1277: ! 1278: assert(kr == KERN_SUCCESS); ! 1279: return kr; ! 1280: } ! 1281: ! 1282: #endif MACH_IPC_COMPAT ! 1283: ! 1284: #include <mach_kdb.h> ! 1285: ! 1286: ! 1287: #if MACH_KDB ! 1288: #define printf kdbprintf ! 1289: ! 1290: /* ! 1291: * Routine: ipc_object_print ! 1292: * Purpose: ! 1293: * Pretty-print an object for kdb. ! 1294: */ ! 1295: ! 1296: char *ikot_print_array[IKOT_MAX_TYPE] = { ! 1297: "(NONE) ", ! 1298: "(THREAD) ", ! 1299: "(TASK) ", ! 1300: "(HOST) ", ! 1301: "(HOST_PRIV) ", ! 1302: "(PROCESSOR) ", ! 1303: "(PSET) ", ! 1304: "(PSET_NAME) ", ! 1305: "(PAGER) ", ! 1306: "(PAGER_REQUEST) ", ! 1307: "(DEVICE) ", /* 10 */ ! 1308: "(XMM_OBJECT) ", ! 1309: "(XMM_PAGER) ", ! 1310: "(XMM_KERNEL) ", ! 1311: "(XMM_REPLY) ", ! 1312: "(PAGER_TERMINATING)", ! 1313: "(PAGING_NAME) ", ! 1314: "(HOST_SECURITY) ", ! 1315: "(LEDGER) ", ! 1316: "(MASTER_DEVICE) ", ! 1317: "(ACTIVATION) ", /* 20 */ ! 1318: "(SUBSYSTEM) ", ! 1319: "(IO_DONE_QUEUE) ", ! 1320: "(SEMAPHORE) ", ! 1321: "(LOCK_SET) ", ! 1322: "(CLOCK) ", ! 1323: "(CLOCK_CTRL) ", /* 26 */ ! 1324: /* << new entries here */ ! 1325: "(UNKNOWN) " /* magic catchall */ ! 1326: }; /* Please keep in sync with kern/ipc_kobject.h */ ! 1327: ! 1328: void ! 1329: ipc_object_print( ! 1330: ipc_object_t object) ! 1331: { ! 1332: int kotype; ! 1333: ! 1334: iprintf("%s", io_active(object) ? "active" : "dead"); ! 1335: printf(", refs=%d", object->io_references); ! 1336: printf(", otype=%d", io_otype(object)); ! 1337: kotype = io_kotype(object); ! 1338: if (kotype >= 0 && kotype < IKOT_MAX_TYPE) ! 1339: printf(", kotype=%d %s\n", io_kotype(object), ! 1340: ikot_print_array[kotype]); ! 1341: else ! 1342: printf(", kotype=0x%x %s\n", io_kotype(object), ! 1343: ikot_print_array[IKOT_UNKNOWN]); ! 1344: } ! 1345: ! 1346: #endif /* MACH_KDB */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.