static void darwin_load_image_infos (struct darwin_info *info) { gdb_byte buf[24]; enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; int len; /* If the structure address is not known, don't continue. */ if (info->all_image_addr == 0) return; /* The structure has 4 fields: version (4 bytes), count (4 bytes), info (pointer) and notifier (pointer). */ len = 4 + 4 + 2 * TYPE_LENGTH (ptr_type); gdb_assert (len <= sizeof (buf)); memset (&info->all_image, 0, sizeof (info->all_image)); /* Read structure raw bytes from target. */ if (target_read_memory (info->all_image_addr, buf, len)) return; /* Extract the fields. */ info->all_image.version = extract_unsigned_integer (buf, 4, byte_order); if (!darwin_dyld_version_ok (info)) return; info->all_image.count = extract_unsigned_integer (buf + 4, 4, byte_order); info->all_image.info = extract_typed_address (buf + 8, ptr_type); info->all_image.notifier = extract_typed_address (buf + 8 + TYPE_LENGTH (ptr_type), ptr_type); }
static void darwin_solib_create_inferior_hook (int from_tty) { struct darwin_info *info = get_darwin_info (); CORE_ADDR load_addr; info->all_image_addr = 0; darwin_solib_read_all_image_info_addr (info); if (info->all_image_addr == 0) darwin_solib_get_all_image_info_addr_at_init (info); if (info->all_image_addr == 0) return; darwin_load_image_infos (info); if (!darwin_dyld_version_ok (info)) { warning (_("unhandled dyld version (%d)"), info->all_image.version); return; } /* Add the breakpoint which is hit by dyld when the list of solib is modified. */ create_solib_event_breakpoint (target_gdbarch (), info->all_image.notifier); if (info->all_image.count != 0) { /* Possible relocate the main executable (PIE). */ load_addr = darwin_read_exec_load_addr_from_dyld (info); } else { /* Possible issue: Do not break on the notifier if dyld is not initialized (deduced from count == 0). In that case, dyld hasn't relocated itself and the notifier may point to a wrong address. */ load_addr = darwin_read_exec_load_addr_at_init (info); } if (load_addr != 0 && symfile_objfile != NULL) { CORE_ADDR vmaddr; /* Find the base address of the executable. */ vmaddr = bfd_mach_o_get_base_address (exec_bfd); /* Relocate. */ if (vmaddr != load_addr) objfile_rebase (symfile_objfile, load_addr - vmaddr); } }
static void darwin_solib_create_inferior_hook (int from_tty) { struct darwin_info *info = get_darwin_info (); CORE_ADDR load_addr; info->all_image_addr = 0; darwin_solib_read_all_image_info_addr (info); if (info->all_image_addr == 0) darwin_solib_get_all_image_info_addr_at_init (info); if (info->all_image_addr == 0) return; darwin_load_image_infos (info); if (!darwin_dyld_version_ok (info)) { warning (_("unhandled dyld version (%d)"), info->all_image.version); return; } create_solib_event_breakpoint (target_gdbarch (), info->all_image.notifier); /* Possible relocate the main executable (PIE). */ load_addr = darwin_read_exec_load_addr (info); if (load_addr != 0 && symfile_objfile != NULL) { CORE_ADDR vmaddr; /* Find the base address of the executable. */ vmaddr = bfd_mach_o_get_base_address (exec_bfd); /* Relocate. */ if (vmaddr != load_addr) objfile_rebase (symfile_objfile, load_addr - vmaddr); } }
static struct so_list * darwin_current_sos (void) { struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); int ptr_len = TYPE_LENGTH (ptr_type); unsigned int image_info_size; struct so_list *head = NULL; struct so_list *tail = NULL; int i; struct darwin_info *info = get_darwin_info (); /* Be sure image infos are loaded. */ darwin_load_image_infos (info); if (!darwin_dyld_version_ok (info)) return NULL; image_info_size = ptr_len * 3; /* Read infos for each solib. The first entry was rumored to be the executable itself, but this is not true when a large number of shared libraries are used (table expanded ?). We now check all entries, but discard executable images. */ for (i = 0; i < info->all_image.count; i++) { CORE_ADDR iinfo = info->all_image.info + i * image_info_size; gdb_byte buf[image_info_size]; CORE_ADDR load_addr; CORE_ADDR path_addr; struct mach_o_header_external hdr; unsigned long hdr_val; char *file_path; int errcode; struct darwin_so_list *dnew; struct so_list *newobj; struct cleanup *old_chain; /* Read image info from inferior. */ if (target_read_memory (iinfo, buf, image_info_size)) break; load_addr = extract_typed_address (buf, ptr_type); path_addr = extract_typed_address (buf + ptr_len, ptr_type); /* Read Mach-O header from memory. */ if (target_read_memory (load_addr, (gdb_byte *) &hdr, sizeof (hdr) - 4)) break; /* Discard wrong magic numbers. Shouldn't happen. */ hdr_val = extract_unsigned_integer (hdr.magic, sizeof (hdr.magic), byte_order); if (hdr_val != BFD_MACH_O_MH_MAGIC && hdr_val != BFD_MACH_O_MH_MAGIC_64) continue; /* Discard executable. Should happen only once. */ hdr_val = extract_unsigned_integer (hdr.filetype, sizeof (hdr.filetype), byte_order); if (hdr_val == BFD_MACH_O_MH_EXECUTE) continue; target_read_string (path_addr, &file_path, SO_NAME_MAX_PATH_SIZE - 1, &errcode); if (errcode) break; /* Create and fill the new so_list element. */ dnew = XCNEW (struct darwin_so_list); newobj = &dnew->sl; old_chain = make_cleanup (xfree, dnew); newobj->lm_info = &dnew->li; strncpy (newobj->so_name, file_path, SO_NAME_MAX_PATH_SIZE - 1); newobj->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; strcpy (newobj->so_original_name, newobj->so_name); xfree (file_path); newobj->lm_info->lm_addr = load_addr; if (head == NULL) head = newobj; else tail->next = newobj; tail = newobj; discard_cleanups (old_chain); } return head; }