- kret = vm_allocate(current_map(), &user_addr, size, VM_FLAGS_ANYWHERE);
- if (kret != KERN_SUCCESS)
- goto out;
-
- kret = mach_make_memory_entry (current_map(), &size, user_addr,
- VM_PROT_DEFAULT, (mem_entry_name_port_t *)&mem_object, 0);
-
- if (kret != KERN_SUCCESS)
- goto out;
-
- vm_deallocate(current_map(), user_addr, size);
-
- shmseg->shm_perm.mode = SHMSEG_ALLOCATED | SHMSEG_REMOVED;
- shmseg->shm_perm.key = uap->key;
- shmseg->shm_perm.seq = (shmseg->shm_perm.seq + 1) & 0x7fff;
- MALLOC(shm_handle, struct shm_handle *, sizeof(struct shm_handle), M_SHM, M_WAITOK);
- if (shm_handle == NULL) {
- kret = KERN_NO_SPACE;
- mach_memory_entry_port_release(mem_object);
- mem_object = NULL;
- goto out;
+ shmseg->u.shm_perm.mode = SHMSEG_ALLOCATED | SHMSEG_REMOVED;
+ shmseg->u.shm_perm._key = uap->key;
+ shmseg->u.shm_perm._seq = (shmseg->u.shm_perm._seq + 1) & 0x7fff;
+
+ shm_handle_next_p = NULL;
+ for (alloc_size = 0;
+ alloc_size < total_size;
+ alloc_size += size) {
+ size = MIN(total_size - alloc_size, ANON_MAX_SIZE);
+ kret = mach_make_memory_entry_64(
+ VM_MAP_NULL,
+ (memory_object_size_t *) &size,
+ (memory_object_offset_t) 0,
+ MAP_MEM_NAMED_CREATE | VM_PROT_DEFAULT,
+ (ipc_port_t *) &mem_object, 0);
+ if (kret != KERN_SUCCESS)
+ goto out;
+
+ MALLOC(shm_handle, struct shm_handle *, sizeof(struct shm_handle), M_SHM, M_WAITOK);
+ if (shm_handle == NULL) {
+ kret = KERN_NO_SPACE;
+ mach_memory_entry_port_release(mem_object);
+ mem_object = NULL;
+ goto out;
+ }
+ shm_handle->shm_object = mem_object;
+ shm_handle->shm_handle_size = size;
+ shm_handle->shm_handle_next = NULL;
+ if (shm_handle_next_p == NULL) {
+ shmseg->u.shm_internal = CAST_USER_ADDR_T(shm_handle);/* tunnel */
+ } else {
+ *shm_handle_next_p = shm_handle;
+ }
+ shm_handle_next_p = &shm_handle->shm_handle_next;