+extern void shared_region_dump_file_entry(
+ int trace_level,
+ load_struct_t *entry); /* forward */
+
+void shared_region_dump_file_entry(
+ int trace_level,
+ load_struct_t *entry)
+{
+ int i;
+ loaded_mapping_t *mapping;
+
+ if (trace_level > shared_region_trace_level) {
+ return;
+ }
+ printf("shared region: %p: "
+ "file_entry %p base_address=0x%x file_offset=0x%x "
+ "%d mappings\n",
+ current_thread(), entry,
+ entry->base_address, entry->file_offset, entry->mapping_cnt);
+ mapping = entry->mappings;
+ for (i = 0; i < entry->mapping_cnt; i++) {
+ printf("shared region: %p:\t#%d: "
+ "offset=0x%x size=0x%x file_offset=0x%x prot=%d\n",
+ current_thread(),
+ i,
+ mapping->mapping_offset,
+ mapping->size,
+ mapping->file_offset,
+ mapping->protection);
+ mapping = mapping->next;
+ }
+}
+
+extern void shared_region_dump_mappings(
+ int trace_level,
+ struct shared_file_mapping_np *mappings,
+ int map_cnt,
+ mach_vm_offset_t base_offset); /* forward */
+
+void shared_region_dump_mappings(
+ int trace_level,
+ struct shared_file_mapping_np *mappings,
+ int map_cnt,
+ mach_vm_offset_t base_offset)
+{
+ int i;
+
+ if (trace_level > shared_region_trace_level) {
+ return;
+ }
+
+ printf("shared region: %p: %d mappings base_offset=0x%llx\n",
+ current_thread(), map_cnt, (uint64_t) base_offset);
+ for (i = 0; i < map_cnt; i++) {
+ printf("shared region: %p:\t#%d: "
+ "addr=0x%llx, size=0x%llx, file_offset=0x%llx, "
+ "prot=(%d,%d)\n",
+ current_thread(),
+ i,
+ (uint64_t) mappings[i].sfm_address,
+ (uint64_t) mappings[i].sfm_size,
+ (uint64_t) mappings[i].sfm_file_offset,
+ mappings[i].sfm_max_prot,
+ mappings[i].sfm_init_prot);
+ }
+}
+
+extern void shared_region_dump_conflict_info(
+ int trace_level,
+ vm_map_t map,
+ vm_map_offset_t offset,
+ vm_map_size_t size); /* forward */
+
+void
+shared_region_dump_conflict_info(
+ int trace_level,
+ vm_map_t map,
+ vm_map_offset_t offset,
+ vm_map_size_t size)
+{
+ vm_map_entry_t entry;
+ vm_object_t object;
+ memory_object_t mem_object;
+ kern_return_t kr;
+ char *filename;
+
+ if (trace_level > shared_region_trace_level) {
+ return;
+ }
+
+ object = VM_OBJECT_NULL;
+
+ vm_map_lock_read(map);
+ if (!vm_map_lookup_entry(map, offset, &entry)) {
+ entry = entry->vme_next;
+ }
+
+ if (entry != vm_map_to_entry(map)) {
+ if (entry->is_sub_map) {
+ printf("shared region: %p: conflict with submap "
+ "at 0x%llx size 0x%llx !?\n",
+ current_thread(),
+ (uint64_t) offset,
+ (uint64_t) size);
+ goto done;
+ }
+
+ object = entry->object.vm_object;
+ if (object == VM_OBJECT_NULL) {
+ printf("shared region: %p: conflict with NULL object "
+ "at 0x%llx size 0x%llx !?\n",
+ current_thread(),
+ (uint64_t) offset,
+ (uint64_t) size);
+ object = VM_OBJECT_NULL;
+ goto done;
+ }
+
+ vm_object_lock(object);
+ while (object->shadow != VM_OBJECT_NULL) {
+ vm_object_t shadow;
+
+ shadow = object->shadow;
+ vm_object_lock(shadow);
+ vm_object_unlock(object);
+ object = shadow;
+ }
+
+ if (object->internal) {
+ printf("shared region: %p: conflict with anonymous "
+ "at 0x%llx size 0x%llx\n",
+ current_thread(),
+ (uint64_t) offset,
+ (uint64_t) size);
+ goto done;
+ }
+ if (! object->pager_ready) {
+ printf("shared region: %p: conflict with uninitialized "
+ "at 0x%llx size 0x%llx\n",
+ current_thread(),
+ (uint64_t) offset,
+ (uint64_t) size);
+ goto done;
+ }
+
+ mem_object = object->pager;
+
+ /*
+ * XXX FBDP: "!internal" doesn't mean it's a vnode pager...
+ */
+ kr = vnode_pager_get_object_filename(mem_object,
+ &filename);
+ if (kr != KERN_SUCCESS) {
+ filename = NULL;
+ }
+ printf("shared region: %p: conflict with '%s' "
+ "at 0x%llx size 0x%llx\n",
+ current_thread(),
+ filename ? filename : "<unknown>",
+ (uint64_t) offset,
+ (uint64_t) size);
+ }
+done:
+ if (object != VM_OBJECT_NULL) {
+ vm_object_unlock(object);
+ }
+ vm_map_unlock_read(map);
+}
+