|
|
1.1.1.2 root 1: /*
1.1 root 2: * Mach Operating System
3: * Copyright (c) 1991,1990 Carnegie Mellon University
4: * All Rights Reserved.
1.1.1.2 root 5: *
1.1 root 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.
1.1.1.2 root 11: *
1.1 root 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.
1.1.1.2 root 15: *
1.1 root 16: * Carnegie Mellon requests users of this software to return to
1.1.1.2 root 17: *
1.1 root 18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
1.1.1.2 root 22: *
1.1 root 23: * any improvements or extensions that they make and grant Carnegie Mellon
24: * the rights to redistribute these changes.
25: */
26: /*
27: */
28: /*
29: * File: ipc/mach_debug.c
30: * Author: Rich Draves
31: * Date: 1989
32: *
33: * Exported kernel calls. See mach_debug/mach_debug.defs.
34: */
35:
1.1.1.3 root 36: #include <string.h>
1.1 root 37:
38: #include <mach/kern_return.h>
39: #include <mach/port.h>
40: #include <mach/machine/vm_types.h>
41: #include <mach/vm_param.h>
42: #include <mach_debug/ipc_info.h>
43: #include <mach_debug/hash_info.h>
44: #include <kern/host.h>
45: #include <vm/vm_map.h>
46: #include <vm/vm_kern.h>
47: #include <ipc/ipc_space.h>
48: #include <ipc/ipc_port.h>
49: #include <ipc/ipc_marequest.h>
50: #include <ipc/ipc_table.h>
51: #include <ipc/ipc_right.h>
52:
53:
54:
55: /*
56: * Routine: mach_port_get_srights [kernel call]
57: * Purpose:
58: * Retrieve the number of extant send rights
59: * that a receive right has.
60: * Conditions:
61: * Nothing locked.
62: * Returns:
63: * KERN_SUCCESS Retrieved number of send rights.
64: * KERN_INVALID_TASK The space is null.
65: * KERN_INVALID_TASK The space is dead.
66: * KERN_INVALID_NAME The name doesn't denote a right.
67: * KERN_INVALID_RIGHT Name doesn't denote receive rights.
68: */
69:
70: kern_return_t
71: mach_port_get_srights(
72: ipc_space_t space,
73: mach_port_t name,
74: mach_port_rights_t *srightsp)
75: {
76: ipc_port_t port;
77: kern_return_t kr;
78: mach_port_rights_t srights;
79:
80: if (space == IS_NULL)
81: return KERN_INVALID_TASK;
82:
83: kr = ipc_port_translate_receive(space, name, &port);
84: if (kr != KERN_SUCCESS)
85: return kr;
86: /* port is locked and active */
87:
88: srights = port->ip_srights;
89: ip_unlock(port);
90:
91: *srightsp = srights;
92: return KERN_SUCCESS;
93: }
94:
95: /*
96: * Routine: host_ipc_marequest_info
97: * Purpose:
98: * Return information about the marequest hash table.
99: * Conditions:
100: * Nothing locked. Obeys CountInOut protocol.
101: * Returns:
102: * KERN_SUCCESS Returned information.
103: * KERN_INVALID_HOST The host is null.
104: * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
105: */
106:
107: kern_return_t
1.1.1.4 root 108: host_ipc_marequest_info(
109: host_t host,
110: unsigned int *maxp,
111: hash_info_bucket_array_t *infop,
112: unsigned int *countp)
1.1 root 113: {
114: vm_offset_t addr;
115: vm_size_t size = 0; /* '=0' to shut up lint */
116: hash_info_bucket_t *info;
117: unsigned int potential, actual;
118: kern_return_t kr;
119:
120: if (host == HOST_NULL)
121: return KERN_INVALID_HOST;
122:
123: /* start with in-line data */
124:
125: info = *infop;
126: potential = *countp;
127:
128: for (;;) {
129: actual = ipc_marequest_info(maxp, info, potential);
130: if (actual <= potential)
131: break;
132:
133: /* allocate more memory */
134:
135: if (info != *infop)
136: kmem_free(ipc_kernel_map, addr, size);
137:
138: size = round_page(actual * sizeof *info);
139: kr = kmem_alloc_pageable(ipc_kernel_map, &addr, size);
140: if (kr != KERN_SUCCESS)
141: return KERN_RESOURCE_SHORTAGE;
142:
143: info = (hash_info_bucket_t *) addr;
144: potential = size/sizeof *info;
145: }
146:
147: if (info == *infop) {
148: /* data fit in-line; nothing to deallocate */
149:
150: *countp = actual;
151: } else if (actual == 0) {
152: kmem_free(ipc_kernel_map, addr, size);
153:
154: *countp = 0;
155: } else {
156: vm_map_copy_t copy;
157: vm_size_t used;
158:
159: used = round_page(actual * sizeof *info);
160:
161: if (used != size)
162: kmem_free(ipc_kernel_map, addr + used, size - used);
163:
164: kr = vm_map_copyin(ipc_kernel_map, addr, used,
165: TRUE, ©);
166: assert(kr == KERN_SUCCESS);
167:
168: *infop = (hash_info_bucket_t *) copy;
169: *countp = actual;
170: }
171:
172: return KERN_SUCCESS;
173: }
174:
175: /*
176: * Routine: mach_port_dnrequest_info
177: * Purpose:
178: * Returns information about the dead-name requests
179: * registered with the named receive right.
180: * Conditions:
181: * Nothing locked.
182: * Returns:
183: * KERN_SUCCESS Retrieved information.
184: * KERN_INVALID_TASK The space is null.
185: * KERN_INVALID_TASK The space is dead.
186: * KERN_INVALID_NAME The name doesn't denote a right.
187: * KERN_INVALID_RIGHT Name doesn't denote receive rights.
188: */
189:
190: kern_return_t
191: mach_port_dnrequest_info(
192: ipc_space_t space,
193: mach_port_t name,
194: unsigned int *totalp,
195: unsigned int *usedp)
196: {
197: unsigned int total, used;
198: ipc_port_t port;
199: kern_return_t kr;
200:
201: if (space == IS_NULL)
202: return KERN_INVALID_TASK;
203:
204: kr = ipc_port_translate_receive(space, name, &port);
205: if (kr != KERN_SUCCESS)
206: return kr;
207: /* port is locked and active */
208:
209: if (port->ip_dnrequests == IPR_NULL) {
210: total = 0;
211: used = 0;
212: } else {
213: ipc_port_request_t dnrequests = port->ip_dnrequests;
214: ipc_port_request_index_t index;
215:
216: total = dnrequests->ipr_size->its_size;
217:
218: for (index = 1, used = 0;
219: index < total; index++) {
220: ipc_port_request_t ipr = &dnrequests[index];
221:
222: if (ipr->ipr_name != MACH_PORT_NULL)
223: used++;
224: }
225: }
226: ip_unlock(port);
227:
228: *totalp = total;
229: *usedp = used;
230: return KERN_SUCCESS;
231: }
232:
233: /*
234: * Routine: mach_port_kernel_object [kernel call]
235: * Purpose:
236: * Retrieve the type and address of the kernel object
237: * represented by a send or receive right.
238: * Conditions:
239: * Nothing locked.
240: * Returns:
241: * KERN_SUCCESS Retrieved kernel object info.
242: * KERN_INVALID_TASK The space is null.
243: * KERN_INVALID_TASK The space is dead.
244: * KERN_INVALID_NAME The name doesn't denote a right.
245: * KERN_INVALID_RIGHT Name doesn't denote
246: * send or receive rights.
247: */
248:
249: kern_return_t
250: mach_port_kernel_object(
251: ipc_space_t space,
252: mach_port_t name,
253: unsigned int *typep,
254: vm_offset_t *addrp)
255: {
256: ipc_entry_t entry;
257: ipc_port_t port;
258: kern_return_t kr;
259:
1.1.1.6 ! root 260: if (space == IS_NULL)
! 261: return KERN_INVALID_TASK;
! 262:
1.1 root 263: kr = ipc_right_lookup_read(space, name, &entry);
264: if (kr != KERN_SUCCESS)
265: return kr;
266: /* space is read-locked and active */
267:
268: if ((entry->ie_bits & MACH_PORT_TYPE_SEND_RECEIVE) == 0) {
269: is_read_unlock(space);
270: return KERN_INVALID_RIGHT;
271: }
272:
273: port = (ipc_port_t) entry->ie_object;
274: assert(port != IP_NULL);
275:
276: ip_lock(port);
277: is_read_unlock(space);
278:
279: if (!ip_active(port)) {
280: ip_unlock(port);
281: return KERN_INVALID_RIGHT;
282: }
283:
1.1.1.4 root 284: *typep = ip_kotype(port);
285: *addrp = port->ip_kobject;
1.1 root 286: ip_unlock(port);
287: return KERN_SUCCESS;
288: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.