X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;ds=sidebyside;f=gdb%2Fsolib-darwin.c;h=ee0483d2c87a2702beb91c343a5bbf5e3ba23dde;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=03211cfb92a6a61baabb9ecab02dbd1985a95b39;hpb=d0e449a1865c741c5e0c9d43a7d61a0621163aa7;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c index 03211cfb92..ee0483d2c8 100644 --- a/gdb/solib-darwin.c +++ b/gdb/solib-darwin.c @@ -1,6 +1,6 @@ /* Handle Darwin shared libraries for GDB, the GNU Debugger. - Copyright (C) 2009-2017 Free Software Foundation, Inc. + Copyright (C) 2009-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -67,26 +67,20 @@ struct gdb_dyld_all_image_infos /* Current all_image_infos version. */ #define DYLD_VERSION_MIN 1 -#define DYLD_VERSION_MAX 14 +#define DYLD_VERSION_MAX 15 /* Per PSPACE specific data. */ struct darwin_info { /* Address of structure dyld_all_image_infos in inferior. */ - CORE_ADDR all_image_addr; + CORE_ADDR all_image_addr = 0; /* Gdb copy of dyld_all_info_infos. */ - struct gdb_dyld_all_image_infos all_image; + struct gdb_dyld_all_image_infos all_image {}; }; /* Per-program-space data key. */ -static const struct program_space_data *solib_darwin_pspace_data; - -static void -darwin_pspace_data_cleanup (struct program_space *pspace, void *arg) -{ - xfree (arg); -} +static program_space_key solib_darwin_pspace_data; /* Get the current darwin data. If none is found yet, add it now. This function always returns a valid object. */ @@ -96,15 +90,11 @@ get_darwin_info (void) { struct darwin_info *info; - info = (struct darwin_info *) program_space_data (current_program_space, - solib_darwin_pspace_data); + info = solib_darwin_pspace_data.get (current_program_space); if (info != NULL) return info; - info = XCNEW (struct darwin_info); - set_program_space_data (current_program_space, - solib_darwin_pspace_data, info); - return info; + return solib_darwin_pspace_data.emplace (current_program_space); } /* Return non-zero if the version in dyld_all_image is known. */ @@ -156,7 +146,7 @@ darwin_load_image_infos (struct darwin_info *info) struct lm_info_darwin : public lm_info_base { /* The target location of lm. */ - CORE_ADDR lm_addr; + CORE_ADDR lm_addr = 0; }; /* Lookup the value for a specific symbol. */ @@ -222,7 +212,7 @@ find_program_interpreter (void) Note that darwin-nat.c implements pid_to_exec_file. */ static int -open_symbol_file_object (void *from_ttyp) +open_symbol_file_object (int from_tty) { return 0; } @@ -233,7 +223,7 @@ 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 ()); + enum bfd_endian byte_order = type_byte_order (ptr_type); int ptr_len = TYPE_LENGTH (ptr_type); unsigned int image_info_size; struct so_list *head = NULL; @@ -261,10 +251,8 @@ darwin_current_sos (void) CORE_ADDR path_addr; struct mach_o_header_external hdr; unsigned long hdr_val; - char *file_path; + gdb::unique_xmalloc_ptr file_path; int errcode; - struct so_list *newobj; - struct cleanup *old_chain; /* Read image info from inferior. */ if (target_read_memory (iinfo, buf, image_info_size)) @@ -293,25 +281,21 @@ darwin_current_sos (void) break; /* Create and fill the new so_list element. */ - newobj = XCNEW (struct so_list); - old_chain = make_cleanup (xfree, newobj); + gdb::unique_xmalloc_ptr newobj (XCNEW (struct so_list)); - lm_info_darwin *li = XCNEW (lm_info_darwin); + lm_info_darwin *li = new lm_info_darwin; newobj->lm_info = li; - strncpy (newobj->so_name, file_path, SO_NAME_MAX_PATH_SIZE - 1); + strncpy (newobj->so_name, file_path.get (), 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); li->lm_addr = load_addr; if (head == NULL) - head = newobj; + head = newobj.get (); else - tail->next = newobj; - tail = newobj; - - discard_cleanups (old_chain); + tail->next = newobj.get (); + tail = newobj.release (); } return head; @@ -435,36 +419,43 @@ gdb_bfd_mach_o_fat_extract (bfd *abfd, bfd_format format, return gdb_bfd_ref_ptr (result); } -/* Extract dyld_all_image_addr when the process was just created, assuming the - current PC is at the entry of the dynamic linker. */ +/* Return the BFD for the program interpreter. */ -static void -darwin_solib_get_all_image_info_addr_at_init (struct darwin_info *info) +static gdb_bfd_ref_ptr +darwin_get_dyld_bfd () { char *interp_name; - CORE_ADDR load_addr = 0; /* This method doesn't work with an attached process. */ if (current_inferior ()->attach_flag) - return; + return NULL; /* Find the program interpreter. */ interp_name = find_program_interpreter (); if (!interp_name) - return; + return NULL; /* Create a bfd for the interpreter. */ - gdb_bfd_ref_ptr dyld_bfd (gdb_bfd_open (interp_name, gnutarget, -1)); + gdb_bfd_ref_ptr dyld_bfd (gdb_bfd_open (interp_name, gnutarget)); if (dyld_bfd != NULL) { gdb_bfd_ref_ptr sub (gdb_bfd_mach_o_fat_extract (dyld_bfd.get (), bfd_object, gdbarch_bfd_arch_info (target_gdbarch ()))); - if (sub != NULL) - dyld_bfd = sub; - else - dyld_bfd.release (); + dyld_bfd = sub; } + return dyld_bfd; +} + +/* Extract dyld_all_image_addr when the process was just created, assuming the + current PC is at the entry of the dynamic linker. */ + +static void +darwin_solib_get_all_image_info_addr_at_init (struct darwin_info *info) +{ + CORE_ADDR load_addr = 0; + gdb_bfd_ref_ptr dyld_bfd = darwin_get_dyld_bfd (); + if (dyld_bfd == NULL) return; @@ -498,8 +489,8 @@ darwin_solib_read_all_image_info_addr (struct darwin_info *info) if (TYPE_LENGTH (ptr_type) > sizeof (buf)) return; - len = target_read (¤t_target, TARGET_OBJECT_DARWIN_DYLD_INFO, NULL, - buf, 0, TYPE_LENGTH (ptr_type)); + len = target_read (current_top_target (), TARGET_OBJECT_DARWIN_DYLD_INFO, + NULL, buf, 0, TYPE_LENGTH (ptr_type)); if (len <= 0) return; @@ -534,10 +525,6 @@ darwin_solib_create_inferior_hook (int from_tty) 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). */ @@ -564,6 +551,49 @@ darwin_solib_create_inferior_hook (int from_tty) if (vmaddr != load_addr) objfile_rebase (symfile_objfile, load_addr - vmaddr); } + + /* Set solib notifier (to reload list of shared libraries). */ + CORE_ADDR notifier = info->all_image.notifier; + + if (info->all_image.count == 0) + { + /* Dyld hasn't yet relocated itself, so the notifier address may + be incorrect (as it has to be relocated). */ + CORE_ADDR start = bfd_get_start_address (exec_bfd); + if (start == 0) + notifier = 0; + else + { + gdb_bfd_ref_ptr dyld_bfd = darwin_get_dyld_bfd (); + if (dyld_bfd != NULL) + { + CORE_ADDR dyld_bfd_start_address; + CORE_ADDR dyld_relocated_base_address; + CORE_ADDR pc; + + dyld_bfd_start_address = bfd_get_start_address (dyld_bfd.get()); + + /* We find the dynamic linker's base address by examining + the current pc (which should point at the entry point + for the dynamic linker) and subtracting the offset of + the entry point. */ + + pc = regcache_read_pc (get_current_regcache ()); + dyld_relocated_base_address = pc - dyld_bfd_start_address; + + /* We get the proper notifier relocated address by + adding the dyld relocated base address to the current + notifier offset value. */ + + notifier += dyld_relocated_base_address; + } + } + } + + /* Add the breakpoint which is hit by dyld when the list of solib is + modified. */ + if (notifier != 0) + create_solib_event_breakpoint (target_gdbarch (), notifier); } static void @@ -578,7 +608,9 @@ darwin_clear_solib (void) static void darwin_free_so (struct so_list *so) { - xfree (so->lm_info); + lm_info_darwin *li = (lm_info_darwin *) so->lm_info; + + delete li; } /* The section table is built from bfd sections using bfd VMAs. @@ -606,27 +638,19 @@ darwin_relocate_section_addresses (struct so_list *so, so->addr_low = sec->addr; } -static struct block_symbol -darwin_lookup_lib_symbol (struct objfile *objfile, - const char *name, - const domain_enum domain) -{ - return (struct block_symbol) {NULL, NULL}; -} - static gdb_bfd_ref_ptr -darwin_bfd_open (char *pathname) +darwin_bfd_open (const char *pathname) { - char *found_pathname; int found_file; /* Search for shared library file. */ - found_pathname = solib_find (pathname, &found_file); + gdb::unique_xmalloc_ptr found_pathname + = solib_find (pathname, &found_file); if (found_pathname == NULL) perror_with_name (pathname); /* Open bfd for shared library. */ - gdb_bfd_ref_ptr abfd (solib_bfd_fopen (found_pathname, found_file)); + gdb_bfd_ref_ptr abfd (solib_bfd_fopen (found_pathname.get (), found_file)); gdb_bfd_ref_ptr res (gdb_bfd_mach_o_fat_extract (abfd.get (), bfd_object, @@ -638,24 +662,17 @@ darwin_bfd_open (char *pathname) /* The current filename for fat-binary BFDs is a name generated by BFD, usually a string containing the name of the architecture. Reset its value to the actual filename. */ - xfree (bfd_get_filename (res.get ())); - res->filename = xstrdup (pathname); + bfd_set_filename (res.get (), pathname); return res; } struct target_so_ops darwin_so_ops; -/* -Wmissing-prototypes */ -extern initialize_file_ftype _initialize_darwin_solib; - +void _initialize_darwin_solib (); void -_initialize_darwin_solib (void) +_initialize_darwin_solib () { - solib_darwin_pspace_data - = register_program_space_data_with_cleanup (NULL, - darwin_pspace_data_cleanup); - darwin_so_ops.relocate_section_addresses = darwin_relocate_section_addresses; darwin_so_ops.free_so = darwin_free_so; darwin_so_ops.clear_solib = darwin_clear_solib; @@ -663,6 +680,5 @@ _initialize_darwin_solib (void) darwin_so_ops.current_sos = darwin_current_sos; darwin_so_ops.open_symbol_file_object = open_symbol_file_object; darwin_so_ops.in_dynsym_resolve_code = darwin_in_dynsym_resolve_code; - darwin_so_ops.lookup_lib_global_symbol = darwin_lookup_lib_symbol; darwin_so_ops.bfd_open = darwin_bfd_open; }