mach_debug.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /*
  2. * Mach Operating System
  3. * Copyright (c) 1991,1990 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 Software.Distribution@CS.CMU.EDU
  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. */
  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. #pragma GCC diagnostic error "-Wundef"
  36. #include <glue/gnulinux.h>
  37. #include <machine/pmap.h>
  38. #include <string.h>
  39. #include <mach/kern_return.h>
  40. #include <mach/port.h>
  41. #include <mach/machine/vm_types.h>
  42. #include <mach/vm_param.h>
  43. #include <mach_debug/ipc_info.h>
  44. #include <mach_debug/hash_info.h>
  45. #include <kern/host.h>
  46. #include <vm/vm_map.h>
  47. #include <vm/vm_kern.h>
  48. #include <ipc/ipc_space.h>
  49. #include <ipc/ipc_port.h>
  50. #include <ipc/ipc_marequest.h>
  51. #include <ipc/ipc_table.h>
  52. #include <ipc/ipc_right.h>
  53. /*
  54. * Routine: mach_port_get_srights [kernel call]
  55. * Purpose:
  56. * Retrieve the number of extant send rights
  57. * that a receive right has.
  58. * Conditions:
  59. * Nothing locked.
  60. * Returns:
  61. * KERN_SUCCESS Retrieved number of send rights.
  62. * KERN_INVALID_TASK The space is null.
  63. * KERN_INVALID_TASK The space is dead.
  64. * KERN_INVALID_NAME The name doesn't denote a right.
  65. * KERN_INVALID_RIGHT Name doesn't denote receive rights.
  66. */
  67. kern_return_t
  68. mach_port_get_srights(
  69. ipc_space_t space,
  70. mach_port_t name,
  71. mach_port_rights_t *srightsp)
  72. {
  73. ipc_port_t port;
  74. kern_return_t kr;
  75. mach_port_rights_t srights;
  76. if (space == IS_NULL)
  77. return KERN_INVALID_TASK;
  78. kr = ipc_port_translate_receive(space, name, &port);
  79. if (kr != KERN_SUCCESS)
  80. return kr;
  81. /* port is locked and active */
  82. srights = port->ip_srights;
  83. ip_unlock(port);
  84. *srightsp = srights;
  85. return KERN_SUCCESS;
  86. }
  87. /*
  88. * Routine: host_ipc_marequest_info
  89. * Purpose:
  90. * Return information about the marequest hash table.
  91. * Conditions:
  92. * Nothing locked. Obeys CountInOut protocol.
  93. * Returns:
  94. * KERN_SUCCESS Returned information.
  95. * KERN_INVALID_HOST The host is null.
  96. * KERN_RESOURCE_SHORTAGE Couldn't allocate memory.
  97. */
  98. #if 0
  99. kern_return_t
  100. host_ipc_marequest_info(
  101. host_t host,
  102. unsigned int *maxp,
  103. hash_info_bucket_array_t *infop,
  104. unsigned int *countp)
  105. {
  106. vm_offset_t addr;
  107. vm_size_t size = 0; /* '=0' to shut up lint */
  108. hash_info_bucket_t *info;
  109. unsigned int potential, actual;
  110. kern_return_t kr;
  111. if (host == HOST_NULL)
  112. return KERN_INVALID_HOST;
  113. /* start with in-line data */
  114. info = *infop;
  115. potential = *countp;
  116. for (;;) {
  117. actual = ipc_marequest_info(maxp, info, potential);
  118. if (actual <= potential)
  119. break;
  120. /* allocate more memory */
  121. if (info != *infop)
  122. kmem_free(ipc_kernel_map, addr, size);
  123. size = round_page(actual * sizeof *info);
  124. kr = kmem_alloc_pageable(ipc_kernel_map, &addr, size);
  125. if (kr != KERN_SUCCESS)
  126. return KERN_RESOURCE_SHORTAGE;
  127. info = (hash_info_bucket_t *) addr;
  128. potential = size/sizeof *info;
  129. }
  130. if (info == *infop) {
  131. /* data fit in-line; nothing to deallocate */
  132. *countp = actual;
  133. } else if (actual == 0) {
  134. kmem_free(ipc_kernel_map, addr, size);
  135. *countp = 0;
  136. } else {
  137. vm_map_copy_t copy;
  138. vm_size_t used;
  139. used = round_page(actual * sizeof *info);
  140. if (used != size)
  141. kmem_free(ipc_kernel_map, addr + used, size - used);
  142. kr = vm_map_copyin(ipc_kernel_map, addr, used,
  143. TRUE, &copy);
  144. assert(kr == KERN_SUCCESS);
  145. *infop = (hash_info_bucket_t *) copy;
  146. *countp = actual;
  147. }
  148. return KERN_SUCCESS;
  149. }
  150. #endif
  151. /*
  152. * Routine: mach_port_dnrequest_info
  153. * Purpose:
  154. * Returns information about the dead-name requests
  155. * registered with the named receive right.
  156. * Conditions:
  157. * Nothing locked.
  158. * Returns:
  159. * KERN_SUCCESS Retrieved information.
  160. * KERN_INVALID_TASK The space is null.
  161. * KERN_INVALID_TASK The space is dead.
  162. * KERN_INVALID_NAME The name doesn't denote a right.
  163. * KERN_INVALID_RIGHT Name doesn't denote receive rights.
  164. */
  165. kern_return_t
  166. mach_port_dnrequest_info(
  167. ipc_space_t space,
  168. mach_port_t name,
  169. unsigned int *totalp,
  170. unsigned int *usedp)
  171. {
  172. unsigned int total, used;
  173. ipc_port_t port;
  174. kern_return_t kr;
  175. if (space == IS_NULL)
  176. return KERN_INVALID_TASK;
  177. kr = ipc_port_translate_receive(space, name, &port);
  178. if (kr != KERN_SUCCESS)
  179. return kr;
  180. /* port is locked and active */
  181. if (port->ip_dnrequests == IPR_NULL) {
  182. total = 0;
  183. used = 0;
  184. } else {
  185. ipc_port_request_t dnrequests = port->ip_dnrequests;
  186. ipc_port_request_index_t index;
  187. total = dnrequests->ipr_size->its_size;
  188. for (index = 1, used = 0;
  189. index < total; index++) {
  190. ipc_port_request_t ipr = &dnrequests[index];
  191. if (ipr->ipr_name != MACH_PORT_NULL)
  192. used++;
  193. }
  194. }
  195. ip_unlock(port);
  196. *totalp = total;
  197. *usedp = used;
  198. return KERN_SUCCESS;
  199. }
  200. /*
  201. * Routine: mach_port_kernel_object [kernel call]
  202. * Purpose:
  203. * Retrieve the type and address of the kernel object
  204. * represented by a send or receive right.
  205. * Conditions:
  206. * Nothing locked.
  207. * Returns:
  208. * KERN_SUCCESS Retrieved kernel object info.
  209. * KERN_INVALID_TASK The space is null.
  210. * KERN_INVALID_TASK The space is dead.
  211. * KERN_INVALID_NAME The name doesn't denote a right.
  212. * KERN_INVALID_RIGHT Name doesn't denote
  213. * send or receive rights.
  214. */
  215. kern_return_t
  216. mach_port_kernel_object(
  217. ipc_space_t space,
  218. mach_port_t name,
  219. unsigned int *typep,
  220. vm_offset_t *addrp)
  221. {
  222. ipc_entry_t entry;
  223. ipc_port_t port;
  224. kern_return_t kr;
  225. if (space == IS_NULL)
  226. return KERN_INVALID_TASK;
  227. kr = ipc_right_lookup_read(space, name, &entry);
  228. if (kr != KERN_SUCCESS)
  229. return kr;
  230. /* space is read-locked and active */
  231. if ((entry->ie_bits & MACH_PORT_TYPE_SEND_RECEIVE) == 0) {
  232. is_read_unlock(space);
  233. return KERN_INVALID_RIGHT;
  234. }
  235. port = (ipc_port_t) entry->ie_object;
  236. assert(port != IP_NULL);
  237. ip_lock(port);
  238. is_read_unlock(space);
  239. if (!ip_active(port)) {
  240. ip_unlock(port);
  241. return KERN_INVALID_RIGHT;
  242. }
  243. *typep = ip_kotype(port);
  244. *addrp = port->ip_kobject;
  245. ip_unlock(port);
  246. return KERN_SUCCESS;
  247. }