+kern_return_t
+mach_memory_entry_access_tracking(
+ ipc_port_t entry_port,
+ int *access_tracking,
+ uint32_t *access_tracking_reads,
+ uint32_t *access_tracking_writes)
+{
+ return memory_entry_access_tracking_internal(entry_port,
+ access_tracking,
+ access_tracking_reads,
+ access_tracking_writes);
+}
+
+kern_return_t
+memory_entry_access_tracking_internal(
+ ipc_port_t entry_port,
+ int *access_tracking,
+ uint32_t *access_tracking_reads,
+ uint32_t *access_tracking_writes)
+{
+ vm_named_entry_t mem_entry;
+ vm_object_t object;
+ kern_return_t kr;
+
+ if (!IP_VALID(entry_port) ||
+ ip_kotype(entry_port) != IKOT_NAMED_ENTRY) {
+ return KERN_INVALID_ARGUMENT;
+ }
+
+ mem_entry = (vm_named_entry_t) entry_port->ip_kobject;
+
+ named_entry_lock(mem_entry);
+
+ if (mem_entry->is_sub_map ||
+ mem_entry->is_copy) {
+ named_entry_unlock(mem_entry);
+ return KERN_INVALID_ARGUMENT;
+ }
+
+ object = mem_entry->backing.object;
+ if (object == VM_OBJECT_NULL) {
+ named_entry_unlock(mem_entry);
+ return KERN_INVALID_ARGUMENT;
+ }
+
+#if VM_OBJECT_ACCESS_TRACKING
+ vm_object_access_tracking(object,
+ access_tracking,
+ access_tracking_reads,
+ access_tracking_writes);
+ kr = KERN_SUCCESS;
+#else /* VM_OBJECT_ACCESS_TRACKING */
+ (void) access_tracking;
+ (void) access_tracking_reads;
+ (void) access_tracking_writes;
+ kr = KERN_NOT_SUPPORTED;
+#endif /* VM_OBJECT_ACCESS_TRACKING */
+
+ named_entry_unlock(mem_entry);
+
+ return kr;
+}
+