- shared_region_mapping_t new_shared_region;
- shared_region_mapping_t next;
- shared_region_mapping_t old_shared_region;
- struct shared_region_task_mappings old_info;
- struct shared_region_task_mappings new_info;
-
- vm_get_shared_region(current_task(), &old_shared_region);
- old_info.self = (vm_offset_t)old_shared_region;
- shared_region_mapping_info(old_shared_region,
- &(old_info.text_region),
- &(old_info.text_size),
- &(old_info.data_region),
- &(old_info.data_size),
- &(old_info.region_mappings),
- &(old_info.client_base),
- &(old_info.alternate_base),
- &(old_info.alternate_next),
- &(old_info.fs_base),
- &(old_info.system),
- &(old_info.flags), &next);
-
- if (shared_regions_active ||
- base_vnode == ENV_DEFAULT_ROOT) {
- if (shared_file_create_system_region(&new_shared_region,
- old_info.fs_base,
- old_info.system))
- return ENOMEM;
- } else {
- if (old_shared_region &&
- base_vnode == ENV_DEFAULT_ROOT) {
- base_vnode = old_info.fs_base;
- }
- new_shared_region =
- lookup_default_shared_region(base_vnode,
- old_info.system);
- if (new_shared_region == NULL) {
- shared_file_boot_time_init(base_vnode,
- old_info.system);
- vm_get_shared_region(current_task(),
- &new_shared_region);
- } else {
- vm_set_shared_region(current_task(), new_shared_region);
- }
- if (old_shared_region)
- shared_region_mapping_dealloc(old_shared_region);
- }
- new_info.self = (vm_offset_t)new_shared_region;
- shared_region_mapping_info(new_shared_region,
- &(new_info.text_region),
- &(new_info.text_size),
- &(new_info.data_region),
- &(new_info.data_size),
- &(new_info.region_mappings),
- &(new_info.client_base),
- &(new_info.alternate_base),
- &(new_info.alternate_next),
- &(new_info.fs_base),
- &(new_info.system),
- &(new_info.flags), &next);
- if(shared_regions_active) {
- if(vm_region_clone(old_info.text_region, new_info.text_region)) {
- panic("clone_system_shared_regions: shared region mis-alignment 1");
- shared_region_mapping_dealloc(new_shared_region);
- return(EINVAL);
- }
- if (vm_region_clone(old_info.data_region, new_info.data_region)) {
- panic("clone_system_shared_regions: shared region mis-alignment 2");
- shared_region_mapping_dealloc(new_shared_region);
- return(EINVAL);
- }
- if (chain_regions) {
- /*
- * We want a "shadowed" clone, a private superset of the old
- * shared region. The info about the old mappings is still
- * valid for us.
- */
- shared_region_object_chain_attach(
- new_shared_region, old_shared_region);
- }
- }
- if (!chain_regions) {
- /*
- * We want a completely detached clone with no link to
- * the old shared region. We'll be removing some mappings
- * in our private, cloned, shared region, so the old mappings
- * will become irrelevant to us. Since we have a private
- * "shared region" now, it isn't going to be shared with
- * anyone else and we won't need to maintain mappings info.
- */
- shared_region_object_chain_detached(new_shared_region);
- }
- if (vm_map_region_replace(current_map(), old_info.text_region,
- new_info.text_region, old_info.client_base,
- old_info.client_base+old_info.text_size)) {
- panic("clone_system_shared_regions: shared region mis-alignment 3");
- shared_region_mapping_dealloc(new_shared_region);
- return(EINVAL);
- }
- if(vm_map_region_replace(current_map(), old_info.data_region,
- new_info.data_region,
- old_info.client_base + old_info.text_size,
- old_info.client_base
- + old_info.text_size + old_info.data_size)) {
- panic("clone_system_shared_regions: shared region mis-alignment 4");
- shared_region_mapping_dealloc(new_shared_region);
- return(EINVAL);
- }
- vm_set_shared_region(current_task(), new_shared_region);
-
- /* consume the reference which wasn't accounted for in object */
- /* chain attach */
- if (!shared_regions_active || !chain_regions)
- shared_region_mapping_dealloc(old_shared_region);
-
- SHARED_REGION_TRACE(
- SHARED_REGION_TRACE_INFO,
- ("shared_region: %p task=%p "
- "clone(active=%d, base=0x%x,chain=%d) "
- "old=%p[%x,%x,%x] new=%p[%x,%x,%x]\n",
- current_thread(), current_task(),
- shared_regions_active, base_vnode, chain_regions,
- old_shared_region,
- old_info.fs_base,
- old_info.system,
- old_info.flags,
- new_shared_region,
- new_info.fs_base,
- new_info.system,
- new_info.flags));
-
- return(0);
-
-}
-
-/* header for the profile name file. The profiled app info is held */
-/* in the data file and pointed to by elements in the name file */
-
-struct profile_names_header {
- unsigned int number_of_profiles;
- unsigned int user_id;
- unsigned int version;
- off_t element_array;
- unsigned int spare1;
- unsigned int spare2;
- unsigned int spare3;
-};