- return (0);
-}
-
-// These are not exported from vm_map.h.
-extern kern_return_t vm_map_write_user(vm_map_t map, void *src_p, vm_map_address_t dst_addr, vm_size_t size);
-
-/* Patches the instructions. Almost like uwrite, but need special instructions on ARM to flush the caches. */
-static
-int patchInst(proc_t *p, void *buf, user_size_t len, user_addr_t a)
-{
- kern_return_t ret;
-
- ASSERT(p != NULL);
- ASSERT(p->task != NULL);
-
- task_t task = p->task;
-
- /*
- * Grab a reference to the task vm_map_t to make sure
- * the map isn't pulled out from under us.
- *
- * Because the proc_lock is not held at all times on all code
- * paths leading here, it is possible for the proc to have
- * exited. If the map is null, fail.
- */
- vm_map_t map = get_task_map_reference(task);
- if (map) {
- /* Find the memory permissions. */
- uint32_t nestingDepth=999999;
- vm_region_submap_short_info_data_64_t info;
- mach_msg_type_number_t count = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
- mach_vm_address_t address = (mach_vm_address_t)a;
- mach_vm_size_t sizeOfRegion = (mach_vm_size_t)len;
-
- ret = mach_vm_region_recurse(map, &address, &sizeOfRegion, &nestingDepth, (vm_region_recurse_info_t)&info, &count);
- if (ret != KERN_SUCCESS)
- goto done;
-
- vm_prot_t reprotect;
-
- if (!(info.protection & VM_PROT_WRITE)) {
- /* Save the original protection values for restoration later */
- reprotect = info.protection;
- if (info.max_protection & VM_PROT_WRITE) {
- /* The memory is not currently writable, but can be made writable. */
- /* Making it both writable and executable at the same time causes warning on embedded */
- ret = mach_vm_protect (map, (mach_vm_offset_t)a, (mach_vm_size_t)len, 0, (reprotect & ~VM_PROT_EXECUTE) | VM_PROT_WRITE);
- } else {
- /*
- * The memory is not currently writable, and cannot be made writable. We need to COW this memory.
- *
- * Strange, we can't just say "reprotect | VM_PROT_COPY", that fails.
- */
- ret = mach_vm_protect (map, (mach_vm_offset_t)a, (mach_vm_size_t)len, 0, VM_PROT_COPY | VM_PROT_READ | VM_PROT_WRITE);
- }
-
- if (ret != KERN_SUCCESS)
- goto done;
-
- } else {
- /* The memory was already writable. */
- reprotect = VM_PROT_NONE;
- }
-
- ret = vm_map_write_user( map,
- buf,
- (vm_map_address_t)a,
- (vm_size_t)len);
-
- flush_caches();
-
- if (ret != KERN_SUCCESS)
- goto done;
-
- if (reprotect != VM_PROT_NONE) {
- ASSERT(reprotect & VM_PROT_EXECUTE);
- ret = mach_vm_protect (map, (mach_vm_offset_t)a, (mach_vm_size_t)len, 0, reprotect);
- }
-
-done:
- vm_map_deallocate(map);
- } else
- ret = KERN_TERMINATED;
-
- return (int)ret;