1cf7f2e2dSJohn Marino /* Definitions for targets which report shared library events. 2cf7f2e2dSJohn Marino 3*ef5ccd6cSJohn Marino Copyright (C) 2007-2013 Free Software Foundation, Inc. 4cf7f2e2dSJohn Marino 5cf7f2e2dSJohn Marino This file is part of GDB. 6cf7f2e2dSJohn Marino 7cf7f2e2dSJohn Marino This program is free software; you can redistribute it and/or modify 8cf7f2e2dSJohn Marino it under the terms of the GNU General Public License as published by 9cf7f2e2dSJohn Marino the Free Software Foundation; either version 3 of the License, or 10cf7f2e2dSJohn Marino (at your option) any later version. 11cf7f2e2dSJohn Marino 12cf7f2e2dSJohn Marino This program is distributed in the hope that it will be useful, 13cf7f2e2dSJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of 14cf7f2e2dSJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15cf7f2e2dSJohn Marino GNU General Public License for more details. 16cf7f2e2dSJohn Marino 17cf7f2e2dSJohn Marino You should have received a copy of the GNU General Public License 18cf7f2e2dSJohn Marino along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19cf7f2e2dSJohn Marino 20cf7f2e2dSJohn Marino #include "defs.h" 21cf7f2e2dSJohn Marino #include "objfiles.h" 22cf7f2e2dSJohn Marino #include "solist.h" 23cf7f2e2dSJohn Marino #include "symtab.h" 24cf7f2e2dSJohn Marino #include "symfile.h" 25cf7f2e2dSJohn Marino #include "target.h" 26cf7f2e2dSJohn Marino #include "vec.h" 27cf7f2e2dSJohn Marino #include "solib-target.h" 28cf7f2e2dSJohn Marino 29cf7f2e2dSJohn Marino #include "gdb_string.h" 30cf7f2e2dSJohn Marino 31cf7f2e2dSJohn Marino /* Private data for each loaded library. */ 32cf7f2e2dSJohn Marino struct lm_info 33cf7f2e2dSJohn Marino { 34cf7f2e2dSJohn Marino /* The library's name. The name is normally kept in the struct 35cf7f2e2dSJohn Marino so_list; it is only here during XML parsing. */ 36cf7f2e2dSJohn Marino char *name; 37cf7f2e2dSJohn Marino 38cf7f2e2dSJohn Marino /* The target can either specify segment bases or section bases, not 39cf7f2e2dSJohn Marino both. */ 40cf7f2e2dSJohn Marino 41cf7f2e2dSJohn Marino /* The base addresses for each independently relocatable segment of 42cf7f2e2dSJohn Marino this shared library. */ 43cf7f2e2dSJohn Marino VEC(CORE_ADDR) *segment_bases; 44cf7f2e2dSJohn Marino 45cf7f2e2dSJohn Marino /* The base addresses for each independently allocatable, 46cf7f2e2dSJohn Marino relocatable section of this shared library. */ 47cf7f2e2dSJohn Marino VEC(CORE_ADDR) *section_bases; 48cf7f2e2dSJohn Marino 49cf7f2e2dSJohn Marino /* The cached offsets for each section of this shared library, 50cf7f2e2dSJohn Marino determined from SEGMENT_BASES, or SECTION_BASES. */ 51cf7f2e2dSJohn Marino struct section_offsets *offsets; 52cf7f2e2dSJohn Marino }; 53cf7f2e2dSJohn Marino 54cf7f2e2dSJohn Marino typedef struct lm_info *lm_info_p; 55cf7f2e2dSJohn Marino DEF_VEC_P(lm_info_p); 56cf7f2e2dSJohn Marino 57cf7f2e2dSJohn Marino #if !defined(HAVE_LIBEXPAT) 58cf7f2e2dSJohn Marino 59cf7f2e2dSJohn Marino static VEC(lm_info_p) * 60cf7f2e2dSJohn Marino solib_target_parse_libraries (const char *library) 61cf7f2e2dSJohn Marino { 62cf7f2e2dSJohn Marino static int have_warned; 63cf7f2e2dSJohn Marino 64cf7f2e2dSJohn Marino if (!have_warned) 65cf7f2e2dSJohn Marino { 66cf7f2e2dSJohn Marino have_warned = 1; 67cf7f2e2dSJohn Marino warning (_("Can not parse XML library list; XML support was disabled " 68cf7f2e2dSJohn Marino "at compile time")); 69cf7f2e2dSJohn Marino } 70cf7f2e2dSJohn Marino 71cf7f2e2dSJohn Marino return NULL; 72cf7f2e2dSJohn Marino } 73cf7f2e2dSJohn Marino 74cf7f2e2dSJohn Marino #else /* HAVE_LIBEXPAT */ 75cf7f2e2dSJohn Marino 76cf7f2e2dSJohn Marino #include "xml-support.h" 77cf7f2e2dSJohn Marino 78cf7f2e2dSJohn Marino /* Handle the start of a <segment> element. */ 79cf7f2e2dSJohn Marino 80cf7f2e2dSJohn Marino static void 81cf7f2e2dSJohn Marino library_list_start_segment (struct gdb_xml_parser *parser, 82cf7f2e2dSJohn Marino const struct gdb_xml_element *element, 83cf7f2e2dSJohn Marino void *user_data, VEC(gdb_xml_value_s) *attributes) 84cf7f2e2dSJohn Marino { 85cf7f2e2dSJohn Marino VEC(lm_info_p) **list = user_data; 86cf7f2e2dSJohn Marino struct lm_info *last = VEC_last (lm_info_p, *list); 87a45ae5f8SJohn Marino ULONGEST *address_p = xml_find_attribute (attributes, "address")->value; 88cf7f2e2dSJohn Marino CORE_ADDR address = (CORE_ADDR) *address_p; 89cf7f2e2dSJohn Marino 90cf7f2e2dSJohn Marino if (last->section_bases != NULL) 91cf7f2e2dSJohn Marino gdb_xml_error (parser, 92cf7f2e2dSJohn Marino _("Library list with both segments and sections")); 93cf7f2e2dSJohn Marino 94a45ae5f8SJohn Marino VEC_safe_push (CORE_ADDR, last->segment_bases, address); 95cf7f2e2dSJohn Marino } 96cf7f2e2dSJohn Marino 97cf7f2e2dSJohn Marino static void 98cf7f2e2dSJohn Marino library_list_start_section (struct gdb_xml_parser *parser, 99cf7f2e2dSJohn Marino const struct gdb_xml_element *element, 100cf7f2e2dSJohn Marino void *user_data, VEC(gdb_xml_value_s) *attributes) 101cf7f2e2dSJohn Marino { 102cf7f2e2dSJohn Marino VEC(lm_info_p) **list = user_data; 103cf7f2e2dSJohn Marino struct lm_info *last = VEC_last (lm_info_p, *list); 104a45ae5f8SJohn Marino ULONGEST *address_p = xml_find_attribute (attributes, "address")->value; 105cf7f2e2dSJohn Marino CORE_ADDR address = (CORE_ADDR) *address_p; 106cf7f2e2dSJohn Marino 107cf7f2e2dSJohn Marino if (last->segment_bases != NULL) 108cf7f2e2dSJohn Marino gdb_xml_error (parser, 109cf7f2e2dSJohn Marino _("Library list with both segments and sections")); 110cf7f2e2dSJohn Marino 111a45ae5f8SJohn Marino VEC_safe_push (CORE_ADDR, last->section_bases, address); 112cf7f2e2dSJohn Marino } 113cf7f2e2dSJohn Marino 114cf7f2e2dSJohn Marino /* Handle the start of a <library> element. */ 115cf7f2e2dSJohn Marino 116cf7f2e2dSJohn Marino static void 117cf7f2e2dSJohn Marino library_list_start_library (struct gdb_xml_parser *parser, 118cf7f2e2dSJohn Marino const struct gdb_xml_element *element, 119cf7f2e2dSJohn Marino void *user_data, VEC(gdb_xml_value_s) *attributes) 120cf7f2e2dSJohn Marino { 121cf7f2e2dSJohn Marino VEC(lm_info_p) **list = user_data; 122cf7f2e2dSJohn Marino struct lm_info *item = XZALLOC (struct lm_info); 123a45ae5f8SJohn Marino const char *name = xml_find_attribute (attributes, "name")->value; 124cf7f2e2dSJohn Marino 125cf7f2e2dSJohn Marino item->name = xstrdup (name); 126cf7f2e2dSJohn Marino VEC_safe_push (lm_info_p, *list, item); 127cf7f2e2dSJohn Marino } 128cf7f2e2dSJohn Marino 129cf7f2e2dSJohn Marino static void 130cf7f2e2dSJohn Marino library_list_end_library (struct gdb_xml_parser *parser, 131cf7f2e2dSJohn Marino const struct gdb_xml_element *element, 132cf7f2e2dSJohn Marino void *user_data, const char *body_text) 133cf7f2e2dSJohn Marino { 134cf7f2e2dSJohn Marino VEC(lm_info_p) **list = user_data; 135cf7f2e2dSJohn Marino struct lm_info *lm_info = VEC_last (lm_info_p, *list); 136cf7f2e2dSJohn Marino 137cf7f2e2dSJohn Marino if (lm_info->segment_bases == NULL 138cf7f2e2dSJohn Marino && lm_info->section_bases == NULL) 139cf7f2e2dSJohn Marino gdb_xml_error (parser, 140cf7f2e2dSJohn Marino _("No segment or section bases defined")); 141cf7f2e2dSJohn Marino } 142cf7f2e2dSJohn Marino 143cf7f2e2dSJohn Marino 144cf7f2e2dSJohn Marino /* Handle the start of a <library-list> element. */ 145cf7f2e2dSJohn Marino 146cf7f2e2dSJohn Marino static void 147cf7f2e2dSJohn Marino library_list_start_list (struct gdb_xml_parser *parser, 148cf7f2e2dSJohn Marino const struct gdb_xml_element *element, 149cf7f2e2dSJohn Marino void *user_data, VEC(gdb_xml_value_s) *attributes) 150cf7f2e2dSJohn Marino { 151a45ae5f8SJohn Marino char *version = xml_find_attribute (attributes, "version")->value; 152cf7f2e2dSJohn Marino 153cf7f2e2dSJohn Marino if (strcmp (version, "1.0") != 0) 154cf7f2e2dSJohn Marino gdb_xml_error (parser, 155cf7f2e2dSJohn Marino _("Library list has unsupported version \"%s\""), 156cf7f2e2dSJohn Marino version); 157cf7f2e2dSJohn Marino } 158cf7f2e2dSJohn Marino 159cf7f2e2dSJohn Marino /* Discard the constructed library list. */ 160cf7f2e2dSJohn Marino 161cf7f2e2dSJohn Marino static void 162cf7f2e2dSJohn Marino solib_target_free_library_list (void *p) 163cf7f2e2dSJohn Marino { 164cf7f2e2dSJohn Marino VEC(lm_info_p) **result = p; 165cf7f2e2dSJohn Marino struct lm_info *info; 166cf7f2e2dSJohn Marino int ix; 167cf7f2e2dSJohn Marino 168cf7f2e2dSJohn Marino for (ix = 0; VEC_iterate (lm_info_p, *result, ix, info); ix++) 169cf7f2e2dSJohn Marino { 170cf7f2e2dSJohn Marino xfree (info->name); 171cf7f2e2dSJohn Marino VEC_free (CORE_ADDR, info->segment_bases); 172cf7f2e2dSJohn Marino VEC_free (CORE_ADDR, info->section_bases); 173cf7f2e2dSJohn Marino xfree (info); 174cf7f2e2dSJohn Marino } 175cf7f2e2dSJohn Marino VEC_free (lm_info_p, *result); 176cf7f2e2dSJohn Marino *result = NULL; 177cf7f2e2dSJohn Marino } 178cf7f2e2dSJohn Marino 179cf7f2e2dSJohn Marino /* The allowed elements and attributes for an XML library list. 180cf7f2e2dSJohn Marino The root element is a <library-list>. */ 181cf7f2e2dSJohn Marino 182a45ae5f8SJohn Marino static const struct gdb_xml_attribute segment_attributes[] = { 183cf7f2e2dSJohn Marino { "address", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 184cf7f2e2dSJohn Marino { NULL, GDB_XML_AF_NONE, NULL, NULL } 185cf7f2e2dSJohn Marino }; 186cf7f2e2dSJohn Marino 187a45ae5f8SJohn Marino static const struct gdb_xml_attribute section_attributes[] = { 188cf7f2e2dSJohn Marino { "address", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 189cf7f2e2dSJohn Marino { NULL, GDB_XML_AF_NONE, NULL, NULL } 190cf7f2e2dSJohn Marino }; 191cf7f2e2dSJohn Marino 192a45ae5f8SJohn Marino static const struct gdb_xml_element library_children[] = { 193cf7f2e2dSJohn Marino { "segment", segment_attributes, NULL, 194cf7f2e2dSJohn Marino GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL, 195cf7f2e2dSJohn Marino library_list_start_segment, NULL }, 196cf7f2e2dSJohn Marino { "section", section_attributes, NULL, 197cf7f2e2dSJohn Marino GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL, 198cf7f2e2dSJohn Marino library_list_start_section, NULL }, 199cf7f2e2dSJohn Marino { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 200cf7f2e2dSJohn Marino }; 201cf7f2e2dSJohn Marino 202a45ae5f8SJohn Marino static const struct gdb_xml_attribute library_attributes[] = { 203cf7f2e2dSJohn Marino { "name", GDB_XML_AF_NONE, NULL, NULL }, 204cf7f2e2dSJohn Marino { NULL, GDB_XML_AF_NONE, NULL, NULL } 205cf7f2e2dSJohn Marino }; 206cf7f2e2dSJohn Marino 207a45ae5f8SJohn Marino static const struct gdb_xml_element library_list_children[] = { 208cf7f2e2dSJohn Marino { "library", library_attributes, library_children, 209cf7f2e2dSJohn Marino GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL, 210cf7f2e2dSJohn Marino library_list_start_library, library_list_end_library }, 211cf7f2e2dSJohn Marino { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 212cf7f2e2dSJohn Marino }; 213cf7f2e2dSJohn Marino 214a45ae5f8SJohn Marino static const struct gdb_xml_attribute library_list_attributes[] = { 215cf7f2e2dSJohn Marino { "version", GDB_XML_AF_NONE, NULL, NULL }, 216cf7f2e2dSJohn Marino { NULL, GDB_XML_AF_NONE, NULL, NULL } 217cf7f2e2dSJohn Marino }; 218cf7f2e2dSJohn Marino 219a45ae5f8SJohn Marino static const struct gdb_xml_element library_list_elements[] = { 220cf7f2e2dSJohn Marino { "library-list", library_list_attributes, library_list_children, 221cf7f2e2dSJohn Marino GDB_XML_EF_NONE, library_list_start_list, NULL }, 222cf7f2e2dSJohn Marino { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 223cf7f2e2dSJohn Marino }; 224cf7f2e2dSJohn Marino 225cf7f2e2dSJohn Marino static VEC(lm_info_p) * 226cf7f2e2dSJohn Marino solib_target_parse_libraries (const char *library) 227cf7f2e2dSJohn Marino { 228cf7f2e2dSJohn Marino VEC(lm_info_p) *result = NULL; 229a45ae5f8SJohn Marino struct cleanup *back_to = make_cleanup (solib_target_free_library_list, 230cf7f2e2dSJohn Marino &result); 231cf7f2e2dSJohn Marino 232a45ae5f8SJohn Marino if (gdb_xml_parse_quick (_("target library list"), "library-list.dtd", 233a45ae5f8SJohn Marino library_list_elements, library, &result) == 0) 234a45ae5f8SJohn Marino { 235a45ae5f8SJohn Marino /* Parsed successfully, keep the result. */ 236a45ae5f8SJohn Marino discard_cleanups (back_to); 237a45ae5f8SJohn Marino return result; 238a45ae5f8SJohn Marino } 239cf7f2e2dSJohn Marino 240cf7f2e2dSJohn Marino do_cleanups (back_to); 241a45ae5f8SJohn Marino return NULL; 242cf7f2e2dSJohn Marino } 243cf7f2e2dSJohn Marino #endif 244cf7f2e2dSJohn Marino 245cf7f2e2dSJohn Marino static struct so_list * 246cf7f2e2dSJohn Marino solib_target_current_sos (void) 247cf7f2e2dSJohn Marino { 248cf7f2e2dSJohn Marino struct so_list *new_solib, *start = NULL, *last = NULL; 249*ef5ccd6cSJohn Marino char *library_document; 250*ef5ccd6cSJohn Marino struct cleanup *old_chain; 251cf7f2e2dSJohn Marino VEC(lm_info_p) *library_list; 252cf7f2e2dSJohn Marino struct lm_info *info; 253cf7f2e2dSJohn Marino int ix; 254cf7f2e2dSJohn Marino 255cf7f2e2dSJohn Marino /* Fetch the list of shared libraries. */ 256cf7f2e2dSJohn Marino library_document = target_read_stralloc (¤t_target, 257cf7f2e2dSJohn Marino TARGET_OBJECT_LIBRARIES, 258cf7f2e2dSJohn Marino NULL); 259cf7f2e2dSJohn Marino if (library_document == NULL) 260cf7f2e2dSJohn Marino return NULL; 261cf7f2e2dSJohn Marino 262*ef5ccd6cSJohn Marino /* solib_target_parse_libraries may throw, so we use a cleanup. */ 263*ef5ccd6cSJohn Marino old_chain = make_cleanup (xfree, library_document); 264*ef5ccd6cSJohn Marino 265cf7f2e2dSJohn Marino /* Parse the list. */ 266cf7f2e2dSJohn Marino library_list = solib_target_parse_libraries (library_document); 267*ef5ccd6cSJohn Marino 268*ef5ccd6cSJohn Marino /* library_document string is not needed behind this point. */ 269*ef5ccd6cSJohn Marino do_cleanups (old_chain); 270*ef5ccd6cSJohn Marino 271cf7f2e2dSJohn Marino if (library_list == NULL) 272cf7f2e2dSJohn Marino return NULL; 273cf7f2e2dSJohn Marino 274cf7f2e2dSJohn Marino /* Build a struct so_list for each entry on the list. */ 275cf7f2e2dSJohn Marino for (ix = 0; VEC_iterate (lm_info_p, library_list, ix, info); ix++) 276cf7f2e2dSJohn Marino { 277cf7f2e2dSJohn Marino new_solib = XZALLOC (struct so_list); 278cf7f2e2dSJohn Marino strncpy (new_solib->so_name, info->name, SO_NAME_MAX_PATH_SIZE - 1); 279cf7f2e2dSJohn Marino new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; 280cf7f2e2dSJohn Marino strncpy (new_solib->so_original_name, info->name, 281cf7f2e2dSJohn Marino SO_NAME_MAX_PATH_SIZE - 1); 282cf7f2e2dSJohn Marino new_solib->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; 283cf7f2e2dSJohn Marino new_solib->lm_info = info; 284cf7f2e2dSJohn Marino 285cf7f2e2dSJohn Marino /* We no longer need this copy of the name. */ 286cf7f2e2dSJohn Marino xfree (info->name); 287cf7f2e2dSJohn Marino info->name = NULL; 288cf7f2e2dSJohn Marino 289cf7f2e2dSJohn Marino /* Add it to the list. */ 290cf7f2e2dSJohn Marino if (!start) 291cf7f2e2dSJohn Marino last = start = new_solib; 292cf7f2e2dSJohn Marino else 293cf7f2e2dSJohn Marino { 294cf7f2e2dSJohn Marino last->next = new_solib; 295cf7f2e2dSJohn Marino last = new_solib; 296cf7f2e2dSJohn Marino } 297cf7f2e2dSJohn Marino } 298cf7f2e2dSJohn Marino 299cf7f2e2dSJohn Marino /* Free the library list, but not its members. */ 300cf7f2e2dSJohn Marino VEC_free (lm_info_p, library_list); 301cf7f2e2dSJohn Marino 302cf7f2e2dSJohn Marino return start; 303cf7f2e2dSJohn Marino } 304cf7f2e2dSJohn Marino 305cf7f2e2dSJohn Marino static void 306cf7f2e2dSJohn Marino solib_target_special_symbol_handling (void) 307cf7f2e2dSJohn Marino { 308cf7f2e2dSJohn Marino /* Nothing needed. */ 309cf7f2e2dSJohn Marino } 310cf7f2e2dSJohn Marino 311cf7f2e2dSJohn Marino static void 312cf7f2e2dSJohn Marino solib_target_solib_create_inferior_hook (int from_tty) 313cf7f2e2dSJohn Marino { 314cf7f2e2dSJohn Marino /* Nothing needed. */ 315cf7f2e2dSJohn Marino } 316cf7f2e2dSJohn Marino 317cf7f2e2dSJohn Marino static void 318cf7f2e2dSJohn Marino solib_target_clear_solib (void) 319cf7f2e2dSJohn Marino { 320cf7f2e2dSJohn Marino /* Nothing needed. */ 321cf7f2e2dSJohn Marino } 322cf7f2e2dSJohn Marino 323cf7f2e2dSJohn Marino static void 324cf7f2e2dSJohn Marino solib_target_free_so (struct so_list *so) 325cf7f2e2dSJohn Marino { 326cf7f2e2dSJohn Marino gdb_assert (so->lm_info->name == NULL); 327cf7f2e2dSJohn Marino xfree (so->lm_info->offsets); 328cf7f2e2dSJohn Marino VEC_free (CORE_ADDR, so->lm_info->segment_bases); 329cf7f2e2dSJohn Marino xfree (so->lm_info); 330cf7f2e2dSJohn Marino } 331cf7f2e2dSJohn Marino 332cf7f2e2dSJohn Marino static void 333cf7f2e2dSJohn Marino solib_target_relocate_section_addresses (struct so_list *so, 334cf7f2e2dSJohn Marino struct target_section *sec) 335cf7f2e2dSJohn Marino { 336cf7f2e2dSJohn Marino CORE_ADDR offset; 337cf7f2e2dSJohn Marino 338cf7f2e2dSJohn Marino /* Build the offset table only once per object file. We can not do 339cf7f2e2dSJohn Marino it any earlier, since we need to open the file first. */ 340cf7f2e2dSJohn Marino if (so->lm_info->offsets == NULL) 341cf7f2e2dSJohn Marino { 342cf7f2e2dSJohn Marino int num_sections = bfd_count_sections (so->abfd); 343cf7f2e2dSJohn Marino 344cf7f2e2dSJohn Marino so->lm_info->offsets = xzalloc (SIZEOF_N_SECTION_OFFSETS (num_sections)); 345cf7f2e2dSJohn Marino 346cf7f2e2dSJohn Marino if (so->lm_info->section_bases) 347cf7f2e2dSJohn Marino { 348cf7f2e2dSJohn Marino int i; 349cf7f2e2dSJohn Marino asection *sect; 350cf7f2e2dSJohn Marino int num_section_bases 351cf7f2e2dSJohn Marino = VEC_length (CORE_ADDR, so->lm_info->section_bases); 352cf7f2e2dSJohn Marino int num_alloc_sections = 0; 353cf7f2e2dSJohn Marino 354cf7f2e2dSJohn Marino for (i = 0, sect = so->abfd->sections; 355cf7f2e2dSJohn Marino sect != NULL; 356cf7f2e2dSJohn Marino i++, sect = sect->next) 357cf7f2e2dSJohn Marino if ((bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC)) 358cf7f2e2dSJohn Marino num_alloc_sections++; 359cf7f2e2dSJohn Marino 360cf7f2e2dSJohn Marino if (num_alloc_sections != num_section_bases) 361cf7f2e2dSJohn Marino warning (_("\ 362cf7f2e2dSJohn Marino Could not relocate shared library \"%s\": wrong number of ALLOC sections"), 363cf7f2e2dSJohn Marino so->so_name); 364cf7f2e2dSJohn Marino else 365cf7f2e2dSJohn Marino { 366cf7f2e2dSJohn Marino int bases_index = 0; 367cf7f2e2dSJohn Marino int found_range = 0; 368cf7f2e2dSJohn Marino CORE_ADDR *section_bases; 369cf7f2e2dSJohn Marino 370cf7f2e2dSJohn Marino section_bases = VEC_address (CORE_ADDR, 371cf7f2e2dSJohn Marino so->lm_info->section_bases); 372cf7f2e2dSJohn Marino 373cf7f2e2dSJohn Marino so->addr_low = ~(CORE_ADDR) 0; 374cf7f2e2dSJohn Marino so->addr_high = 0; 375cf7f2e2dSJohn Marino for (i = 0, sect = so->abfd->sections; 376cf7f2e2dSJohn Marino sect != NULL; 377cf7f2e2dSJohn Marino i++, sect = sect->next) 378cf7f2e2dSJohn Marino { 379cf7f2e2dSJohn Marino if (!(bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC)) 380cf7f2e2dSJohn Marino continue; 381cf7f2e2dSJohn Marino if (bfd_section_size (so->abfd, sect) > 0) 382cf7f2e2dSJohn Marino { 383cf7f2e2dSJohn Marino CORE_ADDR low, high; 384cf7f2e2dSJohn Marino 385cf7f2e2dSJohn Marino low = section_bases[i]; 386cf7f2e2dSJohn Marino high = low + bfd_section_size (so->abfd, sect) - 1; 387cf7f2e2dSJohn Marino 388cf7f2e2dSJohn Marino if (low < so->addr_low) 389cf7f2e2dSJohn Marino so->addr_low = low; 390cf7f2e2dSJohn Marino if (high > so->addr_high) 391cf7f2e2dSJohn Marino so->addr_high = high; 392cf7f2e2dSJohn Marino gdb_assert (so->addr_low <= so->addr_high); 393cf7f2e2dSJohn Marino found_range = 1; 394cf7f2e2dSJohn Marino } 395a45ae5f8SJohn Marino so->lm_info->offsets->offsets[i] 396a45ae5f8SJohn Marino = section_bases[bases_index]; 397cf7f2e2dSJohn Marino bases_index++; 398cf7f2e2dSJohn Marino } 399cf7f2e2dSJohn Marino if (!found_range) 400cf7f2e2dSJohn Marino so->addr_low = so->addr_high = 0; 401cf7f2e2dSJohn Marino gdb_assert (so->addr_low <= so->addr_high); 402cf7f2e2dSJohn Marino } 403cf7f2e2dSJohn Marino } 404cf7f2e2dSJohn Marino else if (so->lm_info->segment_bases) 405cf7f2e2dSJohn Marino { 406cf7f2e2dSJohn Marino struct symfile_segment_data *data; 407cf7f2e2dSJohn Marino 408cf7f2e2dSJohn Marino data = get_symfile_segment_data (so->abfd); 409cf7f2e2dSJohn Marino if (data == NULL) 410cf7f2e2dSJohn Marino warning (_("\ 411cf7f2e2dSJohn Marino Could not relocate shared library \"%s\": no segments"), so->so_name); 412cf7f2e2dSJohn Marino else 413cf7f2e2dSJohn Marino { 414cf7f2e2dSJohn Marino ULONGEST orig_delta; 415cf7f2e2dSJohn Marino int i; 416cf7f2e2dSJohn Marino int num_bases; 417cf7f2e2dSJohn Marino CORE_ADDR *segment_bases; 418cf7f2e2dSJohn Marino 419cf7f2e2dSJohn Marino num_bases = VEC_length (CORE_ADDR, so->lm_info->segment_bases); 420cf7f2e2dSJohn Marino segment_bases = VEC_address (CORE_ADDR, 421cf7f2e2dSJohn Marino so->lm_info->segment_bases); 422cf7f2e2dSJohn Marino 423cf7f2e2dSJohn Marino if (!symfile_map_offsets_to_segments (so->abfd, data, 424cf7f2e2dSJohn Marino so->lm_info->offsets, 425cf7f2e2dSJohn Marino num_bases, segment_bases)) 426cf7f2e2dSJohn Marino warning (_("\ 427cf7f2e2dSJohn Marino Could not relocate shared library \"%s\": bad offsets"), so->so_name); 428cf7f2e2dSJohn Marino 429cf7f2e2dSJohn Marino /* Find the range of addresses to report for this library in 430cf7f2e2dSJohn Marino "info sharedlibrary". Report any consecutive segments 431cf7f2e2dSJohn Marino which were relocated as a single unit. */ 432cf7f2e2dSJohn Marino gdb_assert (num_bases > 0); 433cf7f2e2dSJohn Marino orig_delta = segment_bases[0] - data->segment_bases[0]; 434cf7f2e2dSJohn Marino 435cf7f2e2dSJohn Marino for (i = 1; i < data->num_segments; i++) 436cf7f2e2dSJohn Marino { 437cf7f2e2dSJohn Marino /* If we have run out of offsets, assume all 438cf7f2e2dSJohn Marino remaining segments have the same offset. */ 439cf7f2e2dSJohn Marino if (i >= num_bases) 440cf7f2e2dSJohn Marino continue; 441cf7f2e2dSJohn Marino 442cf7f2e2dSJohn Marino /* If this segment does not have the same offset, do 443cf7f2e2dSJohn Marino not include it in the library's range. */ 444cf7f2e2dSJohn Marino if (segment_bases[i] - data->segment_bases[i] != orig_delta) 445cf7f2e2dSJohn Marino break; 446cf7f2e2dSJohn Marino } 447cf7f2e2dSJohn Marino 448cf7f2e2dSJohn Marino so->addr_low = segment_bases[0]; 449cf7f2e2dSJohn Marino so->addr_high = (data->segment_bases[i - 1] 450cf7f2e2dSJohn Marino + data->segment_sizes[i - 1] 451cf7f2e2dSJohn Marino + orig_delta); 452cf7f2e2dSJohn Marino gdb_assert (so->addr_low <= so->addr_high); 453cf7f2e2dSJohn Marino 454cf7f2e2dSJohn Marino free_symfile_segment_data (data); 455cf7f2e2dSJohn Marino } 456cf7f2e2dSJohn Marino } 457cf7f2e2dSJohn Marino } 458cf7f2e2dSJohn Marino 459cf7f2e2dSJohn Marino offset = so->lm_info->offsets->offsets[sec->the_bfd_section->index]; 460cf7f2e2dSJohn Marino sec->addr += offset; 461cf7f2e2dSJohn Marino sec->endaddr += offset; 462cf7f2e2dSJohn Marino } 463cf7f2e2dSJohn Marino 464cf7f2e2dSJohn Marino static int 465cf7f2e2dSJohn Marino solib_target_open_symbol_file_object (void *from_ttyp) 466cf7f2e2dSJohn Marino { 467cf7f2e2dSJohn Marino /* We can't locate the main symbol file based on the target's 468cf7f2e2dSJohn Marino knowledge; the user has to specify it. */ 469cf7f2e2dSJohn Marino return 0; 470cf7f2e2dSJohn Marino } 471cf7f2e2dSJohn Marino 472cf7f2e2dSJohn Marino static int 473cf7f2e2dSJohn Marino solib_target_in_dynsym_resolve_code (CORE_ADDR pc) 474cf7f2e2dSJohn Marino { 475cf7f2e2dSJohn Marino /* We don't have a range of addresses for the dynamic linker; there 476cf7f2e2dSJohn Marino may not be one in the program's address space. So only report 477cf7f2e2dSJohn Marino PLT entries (which may be import stubs). */ 478cf7f2e2dSJohn Marino return in_plt_section (pc, NULL); 479cf7f2e2dSJohn Marino } 480cf7f2e2dSJohn Marino 481cf7f2e2dSJohn Marino struct target_so_ops solib_target_so_ops; 482cf7f2e2dSJohn Marino 483a45ae5f8SJohn Marino /* -Wmissing-prototypes */ 484a45ae5f8SJohn Marino extern initialize_file_ftype _initialize_solib_target; 485cf7f2e2dSJohn Marino 486cf7f2e2dSJohn Marino void 487cf7f2e2dSJohn Marino _initialize_solib_target (void) 488cf7f2e2dSJohn Marino { 489cf7f2e2dSJohn Marino solib_target_so_ops.relocate_section_addresses 490cf7f2e2dSJohn Marino = solib_target_relocate_section_addresses; 491cf7f2e2dSJohn Marino solib_target_so_ops.free_so = solib_target_free_so; 492cf7f2e2dSJohn Marino solib_target_so_ops.clear_solib = solib_target_clear_solib; 493cf7f2e2dSJohn Marino solib_target_so_ops.solib_create_inferior_hook 494cf7f2e2dSJohn Marino = solib_target_solib_create_inferior_hook; 495cf7f2e2dSJohn Marino solib_target_so_ops.special_symbol_handling 496cf7f2e2dSJohn Marino = solib_target_special_symbol_handling; 497cf7f2e2dSJohn Marino solib_target_so_ops.current_sos = solib_target_current_sos; 498cf7f2e2dSJohn Marino solib_target_so_ops.open_symbol_file_object 499cf7f2e2dSJohn Marino = solib_target_open_symbol_file_object; 500cf7f2e2dSJohn Marino solib_target_so_ops.in_dynsym_resolve_code 501cf7f2e2dSJohn Marino = solib_target_in_dynsym_resolve_code; 502cf7f2e2dSJohn Marino solib_target_so_ops.bfd_open = solib_bfd_open; 503cf7f2e2dSJohn Marino 504cf7f2e2dSJohn Marino /* Set current_target_so_ops to solib_target_so_ops if not already 505cf7f2e2dSJohn Marino set. */ 506cf7f2e2dSJohn Marino if (current_target_so_ops == 0) 507cf7f2e2dSJohn Marino current_target_so_ops = &solib_target_so_ops; 508cf7f2e2dSJohn Marino } 509