+#ifdef IMGPF_POWERPC
+ /*
+ * If we are transitioning to/from powerpc, then we need to do extra
+ * work here.
+ */
+ powerpcParent = (p->p_flag & P_TRANSLATED) ? 1 : 0;
+ powerpcImage = (imgp->ip_flags & IMGPF_POWERPC) ? 1 : 0;
+
+ if (powerpcParent ^ powerpcImage) {
+ cpu_type_t cpu = (powerpcImage ? CPU_TYPE_POWERPC : cpu_type());
+ struct vnode *rootDir = p->p_fd->fd_rdir;
+
+ shared_region = lookup_default_shared_region((int)rootDir, cpu);
+ if (shared_region == NULL) {
+ shared_region_mapping_t old_region;
+ shared_region_mapping_t new_region;
+ vm_get_shared_region(current_task(), &old_region);
+ /* grrrr... this sets current_task(), not task
+ * -- they're different (usually)
+ */
+ shared_file_boot_time_init((int)rootDir,cpu);
+ if ( current_task() != task ) {
+ vm_get_shared_region(current_task(),&new_region);
+ vm_set_shared_region(task,new_region);
+ vm_set_shared_region(current_task(),old_region);
+ }
+ } else {
+ vm_set_shared_region(task, shared_region);
+ }
+ shared_region_mapping_dealloc(initial_region);
+ } else
+#endif /* IMGPF_POWERPC */
+
+ {
+ struct shared_region_task_mappings map_info;
+ shared_region_mapping_t next;
+
+ shared_region_mapping_info(initial_region,
+ &map_info.text_region,
+ &map_info.text_size,
+ &map_info.data_region,
+ &map_info.data_size,
+ &map_info.region_mappings,
+ &map_info.client_base,
+ &map_info.alternate_base,
+ &map_info.alternate_next,
+ &map_info.fs_base,
+ &map_info.system,
+ &map_info.flags,
+ &next);
+ if (map_info.flags & SHARED_REGION_STANDALONE) {
+ /*
+ * We were using a private shared region.
+ * Try and get back to a system-wide shared region
+ * with matching "fs_base" (for chroot) and "system"
+ * (for CPU type).
+ */
+ shared_region = lookup_default_shared_region(
+ map_info.fs_base,
+ map_info.system);
+ if (shared_region == NULL) {
+ /*
+ * No system-wide default regions, stick to
+ * our private region...
+ */
+ } else {
+ SHARED_REGION_TRACE(
+ SHARED_REGION_TRACE_INFO,
+ ("shared_region: %p [%d(%s)] "
+ "exec(\"%s\"): "
+ "moving from private %p[%x,%x,%x] "
+ "to default %p\n",
+ current_thread(),
+ p->p_pid, p->p_comm,
+ (imgp->ip_p_comm[0] ?
+ imgp->ip_p_comm :
+ imgp->ip_ndp->ni_cnd.cn_nameptr),
+ initial_region,
+ map_info.fs_base,
+ map_info.system,
+ map_info.flags,
+ shared_region));
+ vm_set_shared_region(task, shared_region);
+ shared_region_mapping_dealloc(initial_region);
+ }
+ }
+ }
+