From 5e0b8d508ed51004bd836384293be00950ee62c9 Mon Sep 17 00:00:00 2001 From: Pasha Date: Tue, 20 Feb 2024 18:49:50 +0000 Subject: init gnumach copy --- ipc/mach_debug.c | 288 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 ipc/mach_debug.c (limited to 'ipc/mach_debug.c') diff --git a/ipc/mach_debug.c b/ipc/mach_debug.c new file mode 100644 index 0000000..7dca4b6 --- /dev/null +++ b/ipc/mach_debug.c @@ -0,0 +1,288 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: ipc/mach_debug.c + * Author: Rich Draves + * Date: 1989 + * + * Exported kernel calls. See mach_debug/mach_debug.defs. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +/* + * Routine: mach_port_get_srights [kernel call] + * Purpose: + * Retrieve the number of extant send rights + * that a receive right has. + * Conditions: + * Nothing locked. + * Returns: + * KERN_SUCCESS Retrieved number of send rights. + * KERN_INVALID_TASK The space is null. + * KERN_INVALID_TASK The space is dead. + * KERN_INVALID_NAME The name doesn't denote a right. + * KERN_INVALID_RIGHT Name doesn't denote receive rights. + */ + +kern_return_t +mach_port_get_srights( + ipc_space_t space, + mach_port_name_t name, + mach_port_rights_t *srightsp) +{ + ipc_port_t port; + kern_return_t kr; + mach_port_rights_t srights; + + if (space == IS_NULL) + return KERN_INVALID_TASK; + + kr = ipc_port_translate_receive(space, name, &port); + if (kr != KERN_SUCCESS) + return kr; + /* port is locked and active */ + + srights = port->ip_srights; + ip_unlock(port); + + *srightsp = srights; + return KERN_SUCCESS; +} + +/* + * Routine: host_ipc_marequest_info + * Purpose: + * Return information about the marequest hash table. + * Conditions: + * Nothing locked. Obeys CountInOut protocol. + * Returns: + * KERN_SUCCESS Returned information. + * KERN_INVALID_HOST The host is null. + * KERN_RESOURCE_SHORTAGE Couldn't allocate memory. + */ + +kern_return_t +host_ipc_marequest_info( + host_t host, + unsigned int *maxp, + hash_info_bucket_array_t *infop, + unsigned int *countp) +{ + vm_offset_t addr; + vm_size_t size = 0; /* '=0' to shut up lint */ + hash_info_bucket_t *info; + unsigned int potential, actual; + kern_return_t kr; + + if (host == HOST_NULL) + return KERN_INVALID_HOST; + + /* start with in-line data */ + + info = *infop; + potential = *countp; + + for (;;) { + actual = ipc_marequest_info(maxp, info, potential); + if (actual <= potential) + break; + + /* allocate more memory */ + + if (info != *infop) + kmem_free(ipc_kernel_map, addr, size); + + size = round_page(actual * sizeof *info); + kr = kmem_alloc_pageable(ipc_kernel_map, &addr, size); + if (kr != KERN_SUCCESS) + return KERN_RESOURCE_SHORTAGE; + + info = (hash_info_bucket_t *) addr; + potential = size/sizeof *info; + } + + if (info == *infop) { + /* data fit in-line; nothing to deallocate */ + + *countp = actual; + } else if (actual == 0) { + kmem_free(ipc_kernel_map, addr, size); + + *countp = 0; + } else { + vm_map_copy_t copy; + vm_size_t used; + + used = round_page(actual * sizeof *info); + + if (used != size) + kmem_free(ipc_kernel_map, addr + used, size - used); + + kr = vm_map_copyin(ipc_kernel_map, addr, used, + TRUE, ©); + assert(kr == KERN_SUCCESS); + + *infop = (hash_info_bucket_t *) copy; + *countp = actual; + } + + return KERN_SUCCESS; +} + +/* + * Routine: mach_port_dnrequest_info + * Purpose: + * Returns information about the dead-name requests + * registered with the named receive right. + * Conditions: + * Nothing locked. + * Returns: + * KERN_SUCCESS Retrieved information. + * KERN_INVALID_TASK The space is null. + * KERN_INVALID_TASK The space is dead. + * KERN_INVALID_NAME The name doesn't denote a right. + * KERN_INVALID_RIGHT Name doesn't denote receive rights. + */ + +kern_return_t +mach_port_dnrequest_info( + ipc_space_t space, + mach_port_name_t name, + unsigned int *totalp, + unsigned int *usedp) +{ + unsigned int total, used; + ipc_port_t port; + kern_return_t kr; + + if (space == IS_NULL) + return KERN_INVALID_TASK; + + kr = ipc_port_translate_receive(space, name, &port); + if (kr != KERN_SUCCESS) + return kr; + /* port is locked and active */ + + if (port->ip_dnrequests == IPR_NULL) { + total = 0; + used = 0; + } else { + ipc_port_request_t dnrequests = port->ip_dnrequests; + ipc_port_request_index_t index; + + total = dnrequests->ipr_size->its_size; + + for (index = 1, used = 0; + index < total; index++) { + ipc_port_request_t ipr = &dnrequests[index]; + + if (ipr->ipr_name != MACH_PORT_NULL) + used++; + } + } + ip_unlock(port); + + *totalp = total; + *usedp = used; + return KERN_SUCCESS; +} + +/* + * Routine: mach_port_kernel_object [kernel call] + * Purpose: + * Retrieve the type and address of the kernel object + * represented by a send or receive right. + * Conditions: + * Nothing locked. + * Returns: + * KERN_SUCCESS Retrieved kernel object info. + * KERN_INVALID_TASK The space is null. + * KERN_INVALID_TASK The space is dead. + * KERN_INVALID_NAME The name doesn't denote a right. + * KERN_INVALID_RIGHT Name doesn't denote + * send or receive rights. + */ + +kern_return_t +mach_port_kernel_object( + ipc_space_t space, + mach_port_name_t name, + unsigned int *typep, + vm_offset_t *addrp) +{ + ipc_entry_t entry; + ipc_port_t port; + kern_return_t kr; + + if (space == IS_NULL) + return KERN_INVALID_TASK; + + kr = ipc_right_lookup_read(space, name, &entry); + if (kr != KERN_SUCCESS) + return kr; + /* space is read-locked and active */ + + if ((entry->ie_bits & MACH_PORT_TYPE_SEND_RECEIVE) == 0) { + is_read_unlock(space); + return KERN_INVALID_RIGHT; + } + + port = (ipc_port_t) entry->ie_object; + assert(port != IP_NULL); + + ip_lock(port); + is_read_unlock(space); + + if (!ip_active(port)) { + ip_unlock(port); + return KERN_INVALID_RIGHT; + } + + *typep = ip_kotype(port); + *addrp = port->ip_kobject; + ip_unlock(port); + return KERN_SUCCESS; +} -- cgit v1.2.1