diff options
-rw-r--r-- | gdb/ChangeLog | 58 | ||||
-rw-r--r-- | gdb/nto-tdep.c | 35 | ||||
-rw-r--r-- | gdb/solib-aix.c | 62 | ||||
-rw-r--r-- | gdb/solib-darwin.c | 13 | ||||
-rw-r--r-- | gdb/solib-dsbt.c | 22 | ||||
-rw-r--r-- | gdb/solib-frv.c | 49 | ||||
-rw-r--r-- | gdb/solib-svr4.c | 111 | ||||
-rw-r--r-- | gdb/solib-svr4.h | 23 | ||||
-rw-r--r-- | gdb/solib-target.c | 85 | ||||
-rw-r--r-- | gdb/solist.h | 10 | ||||
-rw-r--r-- | gdb/windows-nat.c | 45 |
11 files changed, 291 insertions, 222 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 8f7f552..0b100ac 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,63 @@ 2017-04-28 Simon Marchi <simon.marchi@ericsson.com> + * solist.h (struct lm_info): Remove. + (struct lm_info_base): New class. + (struct so_list) <lm_info>: Change type to lm_info_base *. + * nto-tdep.c (struct lm_info): Remove. + (lm_addr): Adjust. + * solib-aix.c (struct lm_info): Rename to ... + (struct lm_info_aix): ... this. Extend lm_info_base. + (lm_info_p): Rename to ... + (lm_info_aix_p): ... this, and adjust. + (solib_aix_new_lm_info, solib_aix_xfree_lm_info, + solib_aix_parse_libraries, library_list_start_library, + solib_aix_free_library_list, solib_aix_parse_libraries, + solib_aix_get_library_list, + solib_aix_relocate_section_addresses, solib_aix_free_so, + solib_aix_get_section_offsets, + solib_aix_solib_create_inferior_hook, solib_aix_current_sos): + Adjust. + (struct solib_aix_inferior_data) <library_list>: Adjust. + * solib-darwin.c (struct lm_info): Rename to ... + (struct lm_info_darwin): ... this. Extend lm_info_base. + (darwin_current_sos, darwin_relocate_section_addresses): Adjust. + * solib-dsbt.c (struct lm_info): Rename to ... + (struct lm_info_dsbt): ... this. Extend lm_info_base. + (struct dsbt_info) <main_executable_lm_info): Adjust. + (dsbt_current_sos, dsbt_relocate_main_executable, dsbt_free_so, + dsbt_relocate_section_addresses): Adjust. + * solib-frv.c (struct lm_info): Rename to ... + (struct lm_info_frv): ... this. Extend lm_info_base. + (main_executable_lm_info): Adjust. + (frv_current_sos, frv_relocate_main_executable, frv_free_so, + frv_relocate_section_addresses, frv_fdpic_find_global_pointer, + find_canonical_descriptor_in_load_object, + frv_fdpic_find_canonical_descriptor): Adjust. + * solib-svr4.c (struct lm_info): Move to solib-svr4.h, renamed + to lm_info_svr4. + (lm_info_read, lm_addr_check, svr4_keep_data_in_core, + svr4_clear_so, svr4_copy_library_list, + library_list_start_library, svr4_default_sos, svr4_read_so_list, + svr4_current_sos, svr4_fetch_objfile_link_map, + solist_update_incremental): Adjust. + * solib-svr4.h (struct lm_info_svr4): Move here from + solib-svr4.c. + * solib-target.c (struct lm_info): Rename to ... + (struct lm_info_target): ... this. Extend lm_info_base. + (lm_info_p): Rename to ... + (lm_info_target_p): ... this. + (solib_target_parse_libraries, library_list_start_segment, + library_list_start_section, library_list_start_library, + library_list_end_library, solib_target_free_library_list, + solib_target_current_sos, solib_target_free_so, + solib_target_relocate_section_addresses): Adjust. + * windows-nat.c (struct lm_info): Rename to ... + (struct lm_info_windows): ... this. Extend lm_info_base. + (windows_make_so, handle_load_dll, handle_unload_dll, + windows_xfer_shared_libraries): Adjust. + +2017-04-28 Simon Marchi <simon.marchi@ericsson.com> + * solib-darwin.c (struct darwin_so_list): Remove. (darwin_current_sos): Allocate an so_list object instead of a darwin_so_list, separately allocate an lm_info object. diff --git a/gdb/nto-tdep.c b/gdb/nto-tdep.c index 8f8d1d5..f9959ca 100644 --- a/gdb/nto-tdep.c +++ b/gdb/nto-tdep.c @@ -239,43 +239,12 @@ nto_parse_redirection (char *pargv[], const char **pin, const char **pout, return argv; } -/* The struct lm_info, lm_addr, and nto_truncate_ptr are copied from - solib-svr4.c to support nto_relocate_section_addresses - which is different from the svr4 version. */ - -/* Link map info to include in an allocated so_list entry */ - -struct lm_info - { - /* Pointer to copy of link map from inferior. The type is char * - rather than void *, so that we may use byte offsets to find the - various fields without the need for a cast. */ - gdb_byte *lm; - - /* Amount by which addresses in the binary should be relocated to - match the inferior. This could most often be taken directly - from lm, but when prelinking is involved and the prelink base - address changes, we may need a different offset, we want to - warn about the difference and compute it only once. */ - CORE_ADDR l_addr; - - /* The target location of lm. */ - CORE_ADDR lm_addr; - }; - - static CORE_ADDR lm_addr (struct so_list *so) { - if (so->lm_info->l_addr == (CORE_ADDR)-1) - { - struct link_map_offsets *lmo = nto_fetch_link_map_offsets (); - struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; + lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info; - so->lm_info->l_addr = - extract_typed_address (so->lm_info->lm + lmo->l_addr_offset, ptr_type); - } - return so->lm_info->l_addr; + return li->l_addr; } static CORE_ADDR diff --git a/gdb/solib-aix.c b/gdb/solib-aix.c index 66add03..54b8c38 100644 --- a/gdb/solib-aix.c +++ b/gdb/solib-aix.c @@ -33,7 +33,7 @@ static int solib_aix_debug; /* Our private data in struct so_list. */ -struct lm_info +struct lm_info_aix : public lm_info_base { /* The name of the file mapped by the loader. Apart from the entry for the main executable, this is usually a shared library (which, @@ -58,17 +58,17 @@ struct lm_info ULONGEST data_size; }; -typedef struct lm_info *lm_info_p; -DEF_VEC_P(lm_info_p); +typedef lm_info_aix *lm_info_aix_p; +DEF_VEC_P(lm_info_aix_p); /* Return a deep copy of the given struct lm_info object. */ -static struct lm_info * -solib_aix_new_lm_info (struct lm_info *info) +static lm_info_aix * +solib_aix_new_lm_info (lm_info_aix *info) { - struct lm_info *result = XNEW (struct lm_info); + lm_info_aix *result = XCNEW (lm_info_aix); - memcpy (result, info, sizeof (struct lm_info)); + memcpy (result, info, sizeof (lm_info_aix)); result->filename = xstrdup (info->filename); if (info->member_name != NULL) result->member_name = xstrdup (info->member_name); @@ -79,7 +79,7 @@ solib_aix_new_lm_info (struct lm_info *info) /* Free the memory allocated for the given lm_info. */ static void -solib_aix_xfree_lm_info (struct lm_info *info) +solib_aix_xfree_lm_info (lm_info_aix *info) { xfree (info->filename); xfree (info->member_name); @@ -98,7 +98,7 @@ struct solib_aix_inferior_data the same principles applied to shared libraries also apply to the main executable. So it's simpler to keep it as part of this list. */ - VEC (lm_info_p) *library_list; + VEC (lm_info_aix_p) *library_list; }; /* Key to our per-inferior data. */ @@ -127,7 +127,7 @@ get_solib_aix_inferior_data (struct inferior *inf) /* Dummy implementation if XML support is not compiled in. */ -static VEC (lm_info_p) * +static VEC (lm_info_aix_p) * solib_aix_parse_libraries (const char *library) { static int have_warned; @@ -161,8 +161,8 @@ library_list_start_library (struct gdb_xml_parser *parser, void *user_data, VEC (gdb_xml_value_s) *attributes) { - VEC (lm_info_p) **list = (VEC (lm_info_p) **) user_data; - struct lm_info *item = XCNEW (struct lm_info); + VEC (lm_info_aix_p) **list = (VEC (lm_info_aix_p) **) user_data; + lm_info_aix *item = XCNEW (lm_info_aix); struct gdb_xml_value *attr; attr = xml_find_attribute (attributes, "name"); @@ -184,7 +184,7 @@ library_list_start_library (struct gdb_xml_parser *parser, attr = xml_find_attribute (attributes, "data_size"); item->data_size = * (ULONGEST *) attr->value; - VEC_safe_push (lm_info_p, *list, item); + VEC_safe_push (lm_info_aix_p, *list, item); } /* Handle the start of a <library-list-aix> element. */ @@ -207,16 +207,16 @@ library_list_start_list (struct gdb_xml_parser *parser, static void solib_aix_free_library_list (void *p) { - VEC (lm_info_p) **result = (VEC (lm_info_p) **) p; - struct lm_info *info; + VEC (lm_info_aix_p) **result = (VEC (lm_info_aix_p) **) p; + lm_info_aix *info; int ix; if (solib_aix_debug) fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_library_list\n"); - for (ix = 0; VEC_iterate (lm_info_p, *result, ix, info); ix++) + for (ix = 0; VEC_iterate (lm_info_aix_p, *result, ix, info); ix++) solib_aix_xfree_lm_info (info); - VEC_free (lm_info_p, *result); + VEC_free (lm_info_aix_p, *result); *result = NULL; } @@ -256,14 +256,14 @@ static const struct gdb_xml_element library_list_elements[] = }; /* Parse LIBRARY, a string containing the loader info in XML format, - and return an lm_info_p vector. + and return an lm_info_aix_p vector. Return NULL if the parsing failed. */ -static VEC (lm_info_p) * +static VEC (lm_info_aix_p) * solib_aix_parse_libraries (const char *library) { - VEC (lm_info_p) *result = NULL; + VEC (lm_info_aix_p) *result = NULL; struct cleanup *back_to = make_cleanup (solib_aix_free_library_list, &result); @@ -291,7 +291,7 @@ solib_aix_parse_libraries (const char *library) is not NULL, then print a warning including WARNING_MSG and a description of the error. */ -static VEC (lm_info_p) * +static VEC (lm_info_aix_p) * solib_aix_get_library_list (struct inferior *inf, const char *warning_msg) { struct solib_aix_inferior_data *data; @@ -394,7 +394,7 @@ solib_aix_relocate_section_addresses (struct so_list *so, struct bfd_section *bfd_sect = sec->the_bfd_section; bfd *abfd = bfd_sect->owner; const char *section_name = bfd_section_name (abfd, bfd_sect); - struct lm_info *info = so->lm_info; + lm_info_aix *info = (lm_info_aix *) so->lm_info; if (strcmp (section_name, ".text") == 0) { @@ -446,7 +446,7 @@ solib_aix_free_so (struct so_list *so) if (solib_aix_debug) fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_so (%s)\n", so->so_name); - solib_aix_xfree_lm_info (so->lm_info); + solib_aix_xfree_lm_info ((lm_info_aix *) so->lm_info); } /* Implement the "clear_solib" target_so_ops method. */ @@ -465,7 +465,7 @@ solib_aix_clear_solib (void) static struct section_offsets * solib_aix_get_section_offsets (struct objfile *objfile, - struct lm_info *info) + lm_info_aix *info) { struct section_offsets *offsets; bfd *abfd = objfile->obfd; @@ -519,8 +519,8 @@ static void solib_aix_solib_create_inferior_hook (int from_tty) { const char *warning_msg = "unable to relocate main executable"; - VEC (lm_info_p) *library_list; - struct lm_info *exec_info; + VEC (lm_info_aix_p) *library_list; + lm_info_aix *exec_info; /* We need to relocate the main executable... */ @@ -529,13 +529,13 @@ solib_aix_solib_create_inferior_hook (int from_tty) if (library_list == NULL) return; /* Warning already printed. */ - if (VEC_length (lm_info_p, library_list) < 1) + if (VEC_length (lm_info_aix_p, library_list) < 1) { warning (_("unable to relocate main executable (no info from loader)")); return; } - exec_info = VEC_index (lm_info_p, library_list, 0); + exec_info = VEC_index (lm_info_aix_p, library_list, 0); if (symfile_objfile != NULL) { @@ -554,8 +554,8 @@ static struct so_list * solib_aix_current_sos (void) { struct so_list *start = NULL, *last = NULL; - VEC (lm_info_p) *library_list; - struct lm_info *info; + VEC (lm_info_aix_p) *library_list; + lm_info_aix *info; int ix; library_list = solib_aix_get_library_list (current_inferior (), NULL); @@ -565,7 +565,7 @@ solib_aix_current_sos (void) /* Build a struct so_list for each entry on the list. We skip the first entry, since this is the entry corresponding to the main executable, not a shared library. */ - for (ix = 1; VEC_iterate (lm_info_p, library_list, ix, info); ix++) + for (ix = 1; VEC_iterate (lm_info_aix_p, library_list, ix, info); ix++) { struct so_list *new_solib = XCNEW (struct so_list); char *so_name; diff --git a/gdb/solib-darwin.c b/gdb/solib-darwin.c index c507e13..03211cf 100644 --- a/gdb/solib-darwin.c +++ b/gdb/solib-darwin.c @@ -153,7 +153,7 @@ darwin_load_image_infos (struct darwin_info *info) /* Link map info to include in an allocated so_list entry. */ -struct lm_info +struct lm_info_darwin : public lm_info_base { /* The target location of lm. */ CORE_ADDR lm_addr; @@ -296,13 +296,14 @@ darwin_current_sos (void) newobj = XCNEW (struct so_list); old_chain = make_cleanup (xfree, newobj); - newobj->lm_info = XCNEW (struct lm_info); + lm_info_darwin *li = XCNEW (lm_info_darwin); + newobj->lm_info = 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; + li->lm_addr = load_addr; if (head == NULL) head = newobj; @@ -587,8 +588,10 @@ static void darwin_relocate_section_addresses (struct so_list *so, struct target_section *sec) { - sec->addr += so->lm_info->lm_addr; - sec->endaddr += so->lm_info->lm_addr; + lm_info_darwin *li = (lm_info_darwin *) so->lm_info; + + sec->addr += li->lm_addr; + sec->endaddr += li->lm_addr; /* Best effort to set addr_high/addr_low. This is used only by 'info sharedlibary'. */ diff --git a/gdb/solib-dsbt.c b/gdb/solib-dsbt.c index c407106..6d410ac 100644 --- a/gdb/solib-dsbt.c +++ b/gdb/solib-dsbt.c @@ -123,7 +123,7 @@ struct ext_link_map /* Link map info to include in an allocated so_list entry */ -struct lm_info +struct lm_info_dsbt : public lm_info_base { /* The loadmap, digested into an easier to use form. */ struct int_elf32_dsbt_loadmap *map; @@ -137,7 +137,7 @@ struct dsbt_info of loaded shared objects. ``main_executable_lm_info'' provides a way to get at this information so that it doesn't need to be frequently recomputed. Initialized by dsbt_relocate_main_executable. */ - struct lm_info *main_executable_lm_info; + struct lm_info_dsbt *main_executable_lm_info; /* Load maps for the main executable and the interpreter. These are obtained from ptrace. They are the starting point for getting into the program, @@ -711,8 +711,9 @@ dsbt_current_sos (void) } sop = XCNEW (struct so_list); - sop->lm_info = XCNEW (struct lm_info); - sop->lm_info->map = loadmap; + lm_info_dsbt *li = XCNEW (lm_info_dsbt); + sop->lm_info = li; + li->map = loadmap; /* Fetch the name. */ addr = extract_unsigned_integer (lm_buf.l_name, sizeof (lm_buf.l_name), @@ -930,7 +931,7 @@ dsbt_relocate_main_executable (void) ldm = info->exec_loadmap; xfree (info->main_executable_lm_info); - info->main_executable_lm_info = XCNEW (struct lm_info); + info->main_executable_lm_info = XCNEW (lm_info_dsbt); info->main_executable_lm_info->map = ldm; new_offsets = XCNEWVEC (struct section_offsets, @@ -1016,8 +1017,10 @@ dsbt_clear_solib (void) static void dsbt_free_so (struct so_list *so) { - xfree (so->lm_info->map); - xfree (so->lm_info); + lm_info_dsbt *li = (lm_info_dsbt *) so->lm_info; + + xfree (li->map); + xfree (li); } static void @@ -1025,9 +1028,8 @@ dsbt_relocate_section_addresses (struct so_list *so, struct target_section *sec) { int seg; - struct int_elf32_dsbt_loadmap *map; - - map = so->lm_info->map; + lm_info_dsbt *li = (lm_info_dsbt *) so->lm_info; + int_elf32_dsbt_loadmap *map = li->map; for (seg = 0; seg < map->nsegs; seg++) { diff --git a/gdb/solib-frv.c b/gdb/solib-frv.c index e8d5f20..0108d97 100644 --- a/gdb/solib-frv.c +++ b/gdb/solib-frv.c @@ -202,7 +202,7 @@ struct ext_link_map /* Link map info to include in an allocated so_list entry. */ -struct lm_info +struct lm_info_frv : public lm_info_base { /* The loadmap, digested into an easier to use form. */ struct int_elf32_fdpic_loadmap *map; @@ -231,7 +231,7 @@ struct lm_info of loaded shared objects. ``main_executable_lm_info'' provides a way to get at this information so that it doesn't need to be frequently recomputed. Initialized by frv_relocate_main_executable(). */ -static struct lm_info *main_executable_lm_info; +static lm_info_frv *main_executable_lm_info; static void frv_relocate_main_executable (void); static CORE_ADDR main_got (void); @@ -389,10 +389,11 @@ frv_current_sos (void) } sop = XCNEW (struct so_list); - sop->lm_info = XCNEW (struct lm_info); - sop->lm_info->map = loadmap; - sop->lm_info->got_value = got_addr; - sop->lm_info->lm_addr = lm_addr; + lm_info_frv *li = XCNEW (lm_info_frv); + sop->lm_info = li; + li->map = loadmap; + li->got_value = got_addr; + li->lm_addr = lm_addr; /* Fetch the name. */ addr = extract_unsigned_integer (lm_buf.l_name, sizeof (lm_buf.l_name), @@ -783,7 +784,7 @@ frv_relocate_main_executable (void) if (main_executable_lm_info) xfree (main_executable_lm_info); - main_executable_lm_info = XCNEW (struct lm_info); + main_executable_lm_info = XCNEW (lm_info_frv); main_executable_lm_info->map = ldm; new_offsets = XCNEWVEC (struct section_offsets, @@ -870,10 +871,12 @@ frv_clear_solib (void) static void frv_free_so (struct so_list *so) { - xfree (so->lm_info->map); - xfree (so->lm_info->dyn_syms); - xfree (so->lm_info->dyn_relocs); - xfree (so->lm_info); + lm_info_frv *li = (lm_info_frv *) so->lm_info; + + xfree (li->map); + xfree (li->dyn_syms); + xfree (li->dyn_relocs); + xfree (li); } static void @@ -881,9 +884,8 @@ frv_relocate_section_addresses (struct so_list *so, struct target_section *sec) { int seg; - struct int_elf32_fdpic_loadmap *map; - - map = so->lm_info->map; + lm_info_frv *li = (lm_info_frv *) so->lm_info; + int_elf32_fdpic_loadmap *map = li->map; for (seg = 0; seg < map->nsegs; seg++) { @@ -926,15 +928,14 @@ frv_fdpic_find_global_pointer (CORE_ADDR addr) while (so) { int seg; - struct int_elf32_fdpic_loadmap *map; - - map = so->lm_info->map; + lm_info_frv *li = (lm_info_frv *) so->lm_info; + int_elf32_fdpic_loadmap *map = li->map; for (seg = 0; seg < map->nsegs; seg++) { if (map->segs[seg].addr <= addr && addr < map->segs[seg].addr + map->segs[seg].p_memsz) - return so->lm_info->got_value; + return li->got_value; } so = so->next; @@ -947,7 +948,7 @@ frv_fdpic_find_global_pointer (CORE_ADDR addr) /* Forward declarations for frv_fdpic_find_canonical_descriptor(). */ static CORE_ADDR find_canonical_descriptor_in_load_object - (CORE_ADDR, CORE_ADDR, const char *, bfd *, struct lm_info *); + (CORE_ADDR, CORE_ADDR, const char *, bfd *, lm_info_frv *); /* Given a function entry point, attempt to find the canonical descriptor associated with that entry point. Return 0 if no canonical descriptor @@ -987,8 +988,10 @@ frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point) so = master_so_list (); while (so) { + lm_info_frv *li = (lm_info_frv *) so->lm_info; + addr = find_canonical_descriptor_in_load_object - (entry_point, got_value, name, so->abfd, so->lm_info); + (entry_point, got_value, name, so->abfd, li); if (addr != 0) break; @@ -1003,7 +1006,7 @@ frv_fdpic_find_canonical_descriptor (CORE_ADDR entry_point) static CORE_ADDR find_canonical_descriptor_in_load_object (CORE_ADDR entry_point, CORE_ADDR got_value, const char *name, bfd *abfd, - struct lm_info *lm) + lm_info_frv *lm) { enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); arelent *rel; @@ -1141,8 +1144,10 @@ frv_fetch_objfile_link_map (struct objfile *objfile) of shared libraries. */ for (so = master_so_list (); so; so = so->next) { + lm_info_frv *li = (lm_info_frv *) so->lm_info; + if (so->objfile == objfile) - return so->lm_info->lm_addr; + return li->lm_addr; } /* Not found! */ diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 4cb6127..6098d50 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -51,27 +51,6 @@ static int svr4_have_link_map_offsets (void); static void svr4_relocate_main_executable (void); static void svr4_free_library_list (void *p_list); -/* Link map info to include in an allocated so_list entry. */ - -struct lm_info - { - /* Amount by which addresses in the binary should be relocated to - match the inferior. The direct inferior value is L_ADDR_INFERIOR. - When prelinking is involved and the prelink base address changes, - we may need a different offset - the recomputed offset is in L_ADDR. - It is commonly the same value. It is cached as we want to warn about - the difference and compute it only once. L_ADDR is valid - iff L_ADDR_P. */ - CORE_ADDR l_addr, l_addr_inferior; - unsigned int l_addr_p : 1; - - /* The target location of lm. */ - CORE_ADDR lm_addr; - - /* Values read in from inferior's fields of the same name. */ - CORE_ADDR l_ld, l_next, l_prev, l_name; - }; - /* On SVR4 systems, a list of symbols in the dynamic linker where GDB can try to place a breakpoint to monitor shared library events. @@ -189,12 +168,12 @@ svr4_same (struct so_list *gdb, struct so_list *inferior) return (svr4_same_1 (gdb->so_original_name, inferior->so_original_name)); } -static struct lm_info * +static lm_info_svr4 * lm_info_read (CORE_ADDR lm_addr) { struct link_map_offsets *lmo = svr4_fetch_link_map_offsets (); gdb_byte *lm; - struct lm_info *lm_info; + lm_info_svr4 *lm_info; struct cleanup *back_to; lm = (gdb_byte *) xmalloc (lmo->link_map_size); @@ -210,7 +189,7 @@ lm_info_read (CORE_ADDR lm_addr) { struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; - lm_info = XCNEW (struct lm_info); + lm_info = XCNEW (lm_info_svr4); lm_info->lm_addr = lm_addr; lm_info->l_addr_inferior = extract_typed_address (&lm[lmo->l_addr_offset], @@ -240,17 +219,19 @@ has_lm_dynamic_from_link_map (void) static CORE_ADDR lm_addr_check (const struct so_list *so, bfd *abfd) { - if (!so->lm_info->l_addr_p) + lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info; + + if (!li->l_addr_p) { struct bfd_section *dyninfo_sect; CORE_ADDR l_addr, l_dynaddr, dynaddr; - l_addr = so->lm_info->l_addr_inferior; + l_addr = li->l_addr_inferior; if (! abfd || ! has_lm_dynamic_from_link_map ()) goto set_addr; - l_dynaddr = so->lm_info->l_ld; + l_dynaddr = li->l_ld; dyninfo_sect = bfd_get_section_by_name (abfd, ".dynamic"); if (dyninfo_sect == NULL) @@ -333,11 +314,11 @@ lm_addr_check (const struct so_list *so, bfd *abfd) } set_addr: - so->lm_info->l_addr = l_addr; - so->lm_info->l_addr_p = 1; + li->l_addr = l_addr; + li->l_addr_p = 1; } - return so->lm_info->l_addr; + return li->l_addr; } /* Per pspace SVR4 specific data. */ @@ -994,9 +975,10 @@ svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size) newobj = XCNEW (struct so_list); old_chain = make_cleanup (xfree, newobj); - newobj->lm_info = lm_info_read (ldsomap); + lm_info_svr4 *li = lm_info_read (ldsomap); + newobj->lm_info = li; make_cleanup (xfree, newobj->lm_info); - name_lm = newobj->lm_info ? newobj->lm_info->l_name : 0; + name_lm = li != NULL ? li->l_name : 0; do_cleanups (old_chain); return (name_lm >= vaddr && name_lm < vaddr + size); @@ -1106,8 +1088,10 @@ svr4_free_so (struct so_list *so) static void svr4_clear_so (struct so_list *so) { - if (so->lm_info != NULL) - so->lm_info->l_addr_p = 0; + lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info; + + if (li != NULL) + li->l_addr_p = 0; } /* Free so_list built so far (called via cleanup). */ @@ -1141,8 +1125,8 @@ svr4_copy_library_list (struct so_list *src) newobj = XNEW (struct so_list); memcpy (newobj, src, sizeof (struct so_list)); - newobj->lm_info = XNEW (struct lm_info); - memcpy (newobj->lm_info, src->lm_info, sizeof (struct lm_info)); + newobj->lm_info = XNEW (lm_info_svr4); + memcpy (newobj->lm_info, src->lm_info, sizeof (lm_info_svr4)); newobj->next = NULL; *link = newobj; @@ -1178,10 +1162,11 @@ library_list_start_library (struct gdb_xml_parser *parser, struct so_list *new_elem; new_elem = XCNEW (struct so_list); - new_elem->lm_info = XCNEW (struct lm_info); - new_elem->lm_info->lm_addr = *lmp; - new_elem->lm_info->l_addr_inferior = *l_addrp; - new_elem->lm_info->l_ld = *l_ldp; + lm_info_svr4 *li = XCNEW (lm_info_svr4); + new_elem->lm_info = li; + li->lm_addr = *lmp; + li->l_addr_inferior = *l_addrp; + li->l_ld = *l_ldp; strncpy (new_elem->so_name, name, sizeof (new_elem->so_name) - 1); new_elem->so_name[sizeof (new_elem->so_name) - 1] = 0; @@ -1332,12 +1317,12 @@ svr4_default_sos (void) return NULL; newobj = XCNEW (struct so_list); - - newobj->lm_info = XCNEW (struct lm_info); + lm_info_svr4 *li = XCNEW (lm_info_svr4); + newobj->lm_info = li; /* Nothing will ever check the other fields if we set l_addr_p. */ - newobj->lm_info->l_addr = info->debug_loader_offset; - newobj->lm_info->l_addr_p = 1; + li->l_addr = info->debug_loader_offset; + li->l_addr_p = 1; strncpy (newobj->so_name, info->debug_loader_name, SO_NAME_MAX_PATH_SIZE - 1); newobj->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; @@ -1371,20 +1356,21 @@ svr4_read_so_list (CORE_ADDR lm, CORE_ADDR prev_lm, newobj = XCNEW (struct so_list); old_chain = make_cleanup_free_so (newobj); - newobj->lm_info = lm_info_read (lm); - if (newobj->lm_info == NULL) + lm_info_svr4 *li = lm_info_read (lm); + newobj->lm_info = li; + if (li == NULL) { do_cleanups (old_chain); return 0; } - next_lm = newobj->lm_info->l_next; + next_lm = li->l_next; - if (newobj->lm_info->l_prev != prev_lm) + if (li->l_prev != prev_lm) { warning (_("Corrupted shared library list: %s != %s"), paddress (target_gdbarch (), prev_lm), - paddress (target_gdbarch (), newobj->lm_info->l_prev)); + paddress (target_gdbarch (), li->l_prev)); do_cleanups (old_chain); return 0; } @@ -1394,26 +1380,26 @@ svr4_read_so_list (CORE_ADDR lm, CORE_ADDR prev_lm, SVR4, it has no name. For others (Solaris 2.3 for example), it does have a name, so we can no longer use a missing name to decide when to ignore it. */ - if (ignore_first && newobj->lm_info->l_prev == 0) + if (ignore_first && li->l_prev == 0) { struct svr4_info *info = get_svr4_info (); - first_l_name = newobj->lm_info->l_name; - info->main_lm_addr = newobj->lm_info->lm_addr; + first_l_name = li->l_name; + info->main_lm_addr = li->lm_addr; do_cleanups (old_chain); continue; } /* Extract this shared object's name. */ - target_read_string (newobj->lm_info->l_name, &buffer, - SO_NAME_MAX_PATH_SIZE - 1, &errcode); + target_read_string (li->l_name, &buffer, SO_NAME_MAX_PATH_SIZE - 1, + &errcode); if (errcode != 0) { /* If this entry's l_name address matches that of the inferior executable, then this is not a normal shared object, but (most likely) a vDSO. In this case, silently skip it; otherwise emit a warning. */ - if (first_l_name == 0 || newobj->lm_info->l_name != first_l_name) + if (first_l_name == 0 || li->l_name != first_l_name) warning (_("Can't read pathname for load map: %s."), safe_strerror (errcode)); do_cleanups (old_chain); @@ -1594,7 +1580,10 @@ svr4_current_sos (void) [...] [ 9] .dynamic DYNAMIC ffffffffff700580 000580 0000f0 */ - if (address_in_mem_range (so->lm_info->l_ld, &vsyscall_range)) + + lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info; + + if (address_in_mem_range (li->l_ld, &vsyscall_range)) { *sop = so->next; free_so (so); @@ -1628,7 +1617,11 @@ svr4_fetch_objfile_link_map (struct objfile *objfile) of shared libraries. */ for (so = master_so_list (); so; so = so->next) if (so->objfile == objfile) - return so->lm_info->lm_addr; + { + lm_info_svr4 *li = (lm_info_svr4 *) so->lm_info; + + return li->lm_addr; + } /* Not found! */ return 0; @@ -1860,7 +1853,9 @@ solist_update_incremental (struct svr4_info *info, CORE_ADDR lm) /* Walk to the end of the list. */ for (tail = info->solib_list; tail->next != NULL; tail = tail->next) /* Nothing. */; - prev_lm = tail->lm_info->lm_addr; + + lm_info_svr4 *li = (lm_info_svr4 *) tail->lm_info; + prev_lm = li->lm_addr; /* Read the new objects. */ if (info->using_xfer) diff --git a/gdb/solib-svr4.h b/gdb/solib-svr4.h index b97fbd6..a9b09aa 100644 --- a/gdb/solib-svr4.h +++ b/gdb/solib-svr4.h @@ -20,11 +20,34 @@ #ifndef SOLIB_SVR4_H #define SOLIB_SVR4_H +#include "solist.h" + struct objfile; struct target_so_ops; extern struct target_so_ops svr4_so_ops; +/* Link map info to include in an allocated so_list entry. */ + +struct lm_info_svr4 : public lm_info_base +{ + /* Amount by which addresses in the binary should be relocated to + match the inferior. The direct inferior value is L_ADDR_INFERIOR. + When prelinking is involved and the prelink base address changes, + we may need a different offset - the recomputed offset is in L_ADDR. + It is commonly the same value. It is cached as we want to warn about + the difference and compute it only once. L_ADDR is valid + iff L_ADDR_P. */ + CORE_ADDR l_addr, l_addr_inferior; + unsigned int l_addr_p : 1; + + /* The target location of lm. */ + CORE_ADDR lm_addr; + + /* Values read in from inferior's fields of the same name. */ + CORE_ADDR l_ld, l_next, l_prev, l_name; +}; + /* Critical offsets and sizes which describe struct r_debug and struct link_map on SVR4-like targets. All offsets and sizes are in bytes unless otherwise specified. */ diff --git a/gdb/solib-target.c b/gdb/solib-target.c index 1b10e4e..e40acc1 100644 --- a/gdb/solib-target.c +++ b/gdb/solib-target.c @@ -27,7 +27,7 @@ #include "solib-target.h" /* Private data for each loaded library. */ -struct lm_info +struct lm_info_target : public lm_info_base { /* The library's name. The name is normally kept in the struct so_list; it is only here during XML parsing. */ @@ -49,12 +49,12 @@ struct lm_info struct section_offsets *offsets; }; -typedef struct lm_info *lm_info_p; -DEF_VEC_P(lm_info_p); +typedef lm_info_target *lm_info_target_p; +DEF_VEC_P(lm_info_target_p); #if !defined(HAVE_LIBEXPAT) -static VEC(lm_info_p) * +static VEC(lm_info_target_p) * solib_target_parse_libraries (const char *library) { static int have_warned; @@ -80,8 +80,8 @@ library_list_start_segment (struct gdb_xml_parser *parser, const struct gdb_xml_element *element, void *user_data, VEC(gdb_xml_value_s) *attributes) { - VEC(lm_info_p) **list = (VEC(lm_info_p) **) user_data; - struct lm_info *last = VEC_last (lm_info_p, *list); + VEC(lm_info_target_p) **list = (VEC(lm_info_target_p) **) user_data; + lm_info_target *last = VEC_last (lm_info_target_p, *list); ULONGEST *address_p = (ULONGEST *) xml_find_attribute (attributes, "address")->value; CORE_ADDR address = (CORE_ADDR) *address_p; @@ -98,8 +98,8 @@ library_list_start_section (struct gdb_xml_parser *parser, const struct gdb_xml_element *element, void *user_data, VEC(gdb_xml_value_s) *attributes) { - VEC(lm_info_p) **list = (VEC(lm_info_p) **) user_data; - struct lm_info *last = VEC_last (lm_info_p, *list); + VEC(lm_info_target_p) **list = (VEC(lm_info_target_p) **) user_data; + lm_info_target *last = VEC_last (lm_info_target_p, *list); ULONGEST *address_p = (ULONGEST *) xml_find_attribute (attributes, "address")->value; CORE_ADDR address = (CORE_ADDR) *address_p; @@ -118,13 +118,13 @@ library_list_start_library (struct gdb_xml_parser *parser, const struct gdb_xml_element *element, void *user_data, VEC(gdb_xml_value_s) *attributes) { - VEC(lm_info_p) **list = (VEC(lm_info_p) **) user_data; - struct lm_info *item = XCNEW (struct lm_info); + VEC(lm_info_target_p) **list = (VEC(lm_info_target_p) **) user_data; + lm_info_target *item = XCNEW (lm_info_target); const char *name = (const char *) xml_find_attribute (attributes, "name")->value; item->name = xstrdup (name); - VEC_safe_push (lm_info_p, *list, item); + VEC_safe_push (lm_info_target_p, *list, item); } static void @@ -132,8 +132,8 @@ library_list_end_library (struct gdb_xml_parser *parser, const struct gdb_xml_element *element, void *user_data, const char *body_text) { - VEC(lm_info_p) **list = (VEC(lm_info_p) **) user_data; - struct lm_info *lm_info = VEC_last (lm_info_p, *list); + VEC(lm_info_target_p) **list = (VEC(lm_info_target_p) **) user_data; + lm_info_target *lm_info = VEC_last (lm_info_target_p, *list); if (lm_info->segment_bases == NULL && lm_info->section_bases == NULL) @@ -168,18 +168,18 @@ library_list_start_list (struct gdb_xml_parser *parser, static void solib_target_free_library_list (void *p) { - VEC(lm_info_p) **result = (VEC(lm_info_p) **) p; - struct lm_info *info; + VEC(lm_info_target_p) **result = (VEC(lm_info_target_p) **) p; + lm_info_target *info; int ix; - for (ix = 0; VEC_iterate (lm_info_p, *result, ix, info); ix++) + for (ix = 0; VEC_iterate (lm_info_target_p, *result, ix, info); ix++) { xfree (info->name); VEC_free (CORE_ADDR, info->segment_bases); VEC_free (CORE_ADDR, info->section_bases); xfree (info); } - VEC_free (lm_info_p, *result); + VEC_free (lm_info_target_p, *result); *result = NULL; } @@ -229,10 +229,10 @@ static const struct gdb_xml_element library_list_elements[] = { { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } }; -static VEC(lm_info_p) * +static VEC(lm_info_target_p) * solib_target_parse_libraries (const char *library) { - VEC(lm_info_p) *result = NULL; + VEC(lm_info_target_p) *result = NULL; struct cleanup *back_to = make_cleanup (solib_target_free_library_list, &result); @@ -255,8 +255,8 @@ solib_target_current_sos (void) struct so_list *new_solib, *start = NULL, *last = NULL; char *library_document; struct cleanup *old_chain; - VEC(lm_info_p) *library_list; - struct lm_info *info; + VEC(lm_info_target_p) *library_list; + lm_info_target *info; int ix; /* Fetch the list of shared libraries. */ @@ -279,7 +279,7 @@ solib_target_current_sos (void) return NULL; /* Build a struct so_list for each entry on the list. */ - for (ix = 0; VEC_iterate (lm_info_p, library_list, ix, info); ix++) + for (ix = 0; VEC_iterate (lm_info_target_p, library_list, ix, info); ix++) { new_solib = XCNEW (struct so_list); strncpy (new_solib->so_name, info->name, SO_NAME_MAX_PATH_SIZE - 1); @@ -304,7 +304,7 @@ solib_target_current_sos (void) } /* Free the library list, but not its members. */ - VEC_free (lm_info_p, library_list); + VEC_free (lm_info_target_p, library_list); return start; } @@ -324,10 +324,12 @@ solib_target_clear_solib (void) static void solib_target_free_so (struct so_list *so) { - gdb_assert (so->lm_info->name == NULL); - xfree (so->lm_info->offsets); - VEC_free (CORE_ADDR, so->lm_info->segment_bases); - xfree (so->lm_info); + lm_info_target *li = (lm_info_target *) so->lm_info; + + gdb_assert (li->name == NULL); + xfree (li->offsets); + VEC_free (CORE_ADDR, li->segment_bases); + xfree (li); } static void @@ -335,23 +337,24 @@ solib_target_relocate_section_addresses (struct so_list *so, struct target_section *sec) { CORE_ADDR offset; + lm_info_target *li = (lm_info_target *) so->lm_info; /* Build the offset table only once per object file. We can not do it any earlier, since we need to open the file first. */ - if (so->lm_info->offsets == NULL) + if (li->offsets == NULL) { int num_sections = gdb_bfd_count_sections (so->abfd); - so->lm_info->offsets + li->offsets = ((struct section_offsets *) xzalloc (SIZEOF_N_SECTION_OFFSETS (num_sections))); - if (so->lm_info->section_bases) + if (li->section_bases) { int i; asection *sect; int num_section_bases - = VEC_length (CORE_ADDR, so->lm_info->section_bases); + = VEC_length (CORE_ADDR, li->section_bases); int num_alloc_sections = 0; for (i = 0, sect = so->abfd->sections; @@ -371,7 +374,7 @@ Could not relocate shared library \"%s\": wrong number of ALLOC sections"), CORE_ADDR *section_bases; section_bases = VEC_address (CORE_ADDR, - so->lm_info->section_bases); + li->section_bases); so->addr_low = ~(CORE_ADDR) 0; so->addr_high = 0; @@ -395,7 +398,7 @@ Could not relocate shared library \"%s\": wrong number of ALLOC sections"), gdb_assert (so->addr_low <= so->addr_high); found_range = 1; } - so->lm_info->offsets->offsets[i] + li->offsets->offsets[i] = section_bases[bases_index]; bases_index++; } @@ -404,7 +407,7 @@ Could not relocate shared library \"%s\": wrong number of ALLOC sections"), gdb_assert (so->addr_low <= so->addr_high); } } - else if (so->lm_info->segment_bases) + else if (li->segment_bases) { struct symfile_segment_data *data; @@ -419,12 +422,10 @@ Could not relocate shared library \"%s\": no segments"), so->so_name); int num_bases; CORE_ADDR *segment_bases; - num_bases = VEC_length (CORE_ADDR, so->lm_info->segment_bases); - segment_bases = VEC_address (CORE_ADDR, - so->lm_info->segment_bases); + num_bases = VEC_length (CORE_ADDR, li->segment_bases); + segment_bases = VEC_address (CORE_ADDR, li->segment_bases); - if (!symfile_map_offsets_to_segments (so->abfd, data, - so->lm_info->offsets, + if (!symfile_map_offsets_to_segments (so->abfd, data, li->offsets, num_bases, segment_bases)) warning (_("\ Could not relocate shared library \"%s\": bad offsets"), so->so_name); @@ -459,9 +460,9 @@ Could not relocate shared library \"%s\": bad offsets"), so->so_name); } } - offset = so->lm_info->offsets->offsets[gdb_bfd_section_index - (sec->the_bfd_section->owner, - sec->the_bfd_section)]; + offset = li->offsets->offsets[gdb_bfd_section_index + (sec->the_bfd_section->owner, + sec->the_bfd_section)]; sec->addr += offset; sec->endaddr += offset; } diff --git a/gdb/solist.h b/gdb/solist.h index 378d60d..54c9902 100644 --- a/gdb/solist.h +++ b/gdb/solist.h @@ -29,9 +29,11 @@ so != NULL; \ so = so->next) -/* Forward declaration for target specific link map information. This - struct is opaque to all but the target specific file. */ -struct lm_info; +/* Base class for target-specific link map information. */ + +struct lm_info_base +{ +}; struct so_list { @@ -45,7 +47,7 @@ struct so_list will be a copy of struct link_map from the user process, but it need not be; it can be any collection of data needed to traverse the dynamic linker's data structures. */ - struct lm_info *lm_info; + lm_info_base *lm_info; /* Shared object file name, exactly as it appears in the inferior's link map. This may be a relative path, or something diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index 805fb43..ef1c291 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -585,7 +585,7 @@ struct safe_symbol_file_add_args }; /* Maintain a linked list of "so" information. */ -struct lm_info +struct lm_info_windows : public lm_info_base { LPVOID load_addr; }; @@ -645,8 +645,9 @@ windows_make_so (const char *name, LPVOID load_addr) } #endif so = XCNEW (struct so_list); - so->lm_info = XNEW (struct lm_info); - so->lm_info->load_addr = load_addr; + lm_info_windows *li = XCNEW (struct lm_info_windows); + so->lm_info = li; + li->load_addr = load_addr; strcpy (so->so_original_name, name); #ifndef __CYGWIN__ strcpy (so->so_name, buf); @@ -772,8 +773,10 @@ handle_load_dll (void *dummy) solib_end->next = windows_make_so (dll_name, event->lpBaseOfDll); solib_end = solib_end->next; + lm_info_windows *li = (lm_info_windows *) solib_end->lm_info; + DEBUG_EVENTS (("gdb: Loading dll \"%s\" at %s.\n", solib_end->so_name, - host_address_to_string (solib_end->lm_info->load_addr))); + host_address_to_string (li->load_addr))); return 1; } @@ -801,18 +804,22 @@ handle_unload_dll (void *dummy) struct so_list *so; for (so = &solib_start; so->next != NULL; so = so->next) - if (so->next->lm_info->load_addr == lpBaseOfDll) - { - struct so_list *sodel = so->next; + { + lm_info_windows *li_next = (lm_info_windows *) so->next->lm_info; - so->next = sodel->next; - if (!so->next) - solib_end = so; - DEBUG_EVENTS (("gdb: Unloading dll \"%s\".\n", sodel->so_name)); + if (li_next->load_addr == lpBaseOfDll) + { + struct so_list *sodel = so->next; - windows_free_so (sodel); - return 1; - } + so->next = sodel->next; + if (!so->next) + solib_end = so; + DEBUG_EVENTS (("gdb: Unloading dll \"%s\".\n", sodel->so_name)); + + windows_free_so (sodel); + return 1; + } + } /* We did not find any DLL that was previously loaded at this address, so register a complaint. We do not report an error, because we have @@ -2842,9 +2849,13 @@ windows_xfer_shared_libraries (struct target_ops *ops, obstack_init (&obstack); obstack_grow_str (&obstack, "<library-list>\n"); for (so = solib_start.next; so; so = so->next) - windows_xfer_shared_library (so->so_name, (CORE_ADDR) - (uintptr_t) so->lm_info->load_addr, - target_gdbarch (), &obstack); + { + lm_info_windows *li = (lm_info_windows *) so->lm_info; + + windows_xfer_shared_library (so->so_name, (CORE_ADDR) + (uintptr_t) li->load_addr, + target_gdbarch (), &obstack); + } obstack_grow_str0 (&obstack, "</library-list>\n"); buf = (const char *) obstack_finish (&obstack); |