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