1cf7f2e2dSJohn Marino /* Definitions for targets which report shared library events. 2cf7f2e2dSJohn Marino 3*a45ae5f8SJohn Marino Copyright (C) 2007-2012 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); 87*a45ae5f8SJohn 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 94*a45ae5f8SJohn 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); 104*a45ae5f8SJohn 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 111*a45ae5f8SJohn 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); 123*a45ae5f8SJohn 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 { 151*a45ae5f8SJohn 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 182*a45ae5f8SJohn 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 187*a45ae5f8SJohn 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 192*a45ae5f8SJohn 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 202*a45ae5f8SJohn 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 207*a45ae5f8SJohn 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 214*a45ae5f8SJohn 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 219*a45ae5f8SJohn 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; 229*a45ae5f8SJohn Marino struct cleanup *back_to = make_cleanup (solib_target_free_library_list, 230cf7f2e2dSJohn Marino &result); 231cf7f2e2dSJohn Marino 232*a45ae5f8SJohn Marino if (gdb_xml_parse_quick (_("target library list"), "library-list.dtd", 233*a45ae5f8SJohn Marino library_list_elements, library, &result) == 0) 234*a45ae5f8SJohn Marino { 235*a45ae5f8SJohn Marino /* Parsed successfully, keep the result. */ 236*a45ae5f8SJohn Marino discard_cleanups (back_to); 237*a45ae5f8SJohn Marino return result; 238*a45ae5f8SJohn Marino } 239cf7f2e2dSJohn Marino 240cf7f2e2dSJohn Marino do_cleanups (back_to); 241*a45ae5f8SJohn 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; 249cf7f2e2dSJohn Marino const char *library_document; 250cf7f2e2dSJohn Marino VEC(lm_info_p) *library_list; 251cf7f2e2dSJohn Marino struct lm_info *info; 252cf7f2e2dSJohn Marino int ix; 253cf7f2e2dSJohn Marino 254cf7f2e2dSJohn Marino /* Fetch the list of shared libraries. */ 255cf7f2e2dSJohn Marino library_document = target_read_stralloc (¤t_target, 256cf7f2e2dSJohn Marino TARGET_OBJECT_LIBRARIES, 257cf7f2e2dSJohn Marino NULL); 258cf7f2e2dSJohn Marino if (library_document == NULL) 259cf7f2e2dSJohn Marino return NULL; 260cf7f2e2dSJohn Marino 261cf7f2e2dSJohn Marino /* Parse the list. */ 262cf7f2e2dSJohn Marino library_list = solib_target_parse_libraries (library_document); 263cf7f2e2dSJohn Marino if (library_list == NULL) 264cf7f2e2dSJohn Marino return NULL; 265cf7f2e2dSJohn Marino 266cf7f2e2dSJohn Marino /* Build a struct so_list for each entry on the list. */ 267cf7f2e2dSJohn Marino for (ix = 0; VEC_iterate (lm_info_p, library_list, ix, info); ix++) 268cf7f2e2dSJohn Marino { 269cf7f2e2dSJohn Marino new_solib = XZALLOC (struct so_list); 270cf7f2e2dSJohn Marino strncpy (new_solib->so_name, info->name, SO_NAME_MAX_PATH_SIZE - 1); 271cf7f2e2dSJohn Marino new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; 272cf7f2e2dSJohn Marino strncpy (new_solib->so_original_name, info->name, 273cf7f2e2dSJohn Marino SO_NAME_MAX_PATH_SIZE - 1); 274cf7f2e2dSJohn Marino new_solib->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; 275cf7f2e2dSJohn Marino new_solib->lm_info = info; 276cf7f2e2dSJohn Marino 277cf7f2e2dSJohn Marino /* We no longer need this copy of the name. */ 278cf7f2e2dSJohn Marino xfree (info->name); 279cf7f2e2dSJohn Marino info->name = NULL; 280cf7f2e2dSJohn Marino 281cf7f2e2dSJohn Marino /* Add it to the list. */ 282cf7f2e2dSJohn Marino if (!start) 283cf7f2e2dSJohn Marino last = start = new_solib; 284cf7f2e2dSJohn Marino else 285cf7f2e2dSJohn Marino { 286cf7f2e2dSJohn Marino last->next = new_solib; 287cf7f2e2dSJohn Marino last = new_solib; 288cf7f2e2dSJohn Marino } 289cf7f2e2dSJohn Marino } 290cf7f2e2dSJohn Marino 291cf7f2e2dSJohn Marino /* Free the library list, but not its members. */ 292cf7f2e2dSJohn Marino VEC_free (lm_info_p, library_list); 293cf7f2e2dSJohn Marino 294cf7f2e2dSJohn Marino return start; 295cf7f2e2dSJohn Marino } 296cf7f2e2dSJohn Marino 297cf7f2e2dSJohn Marino static void 298cf7f2e2dSJohn Marino solib_target_special_symbol_handling (void) 299cf7f2e2dSJohn Marino { 300cf7f2e2dSJohn Marino /* Nothing needed. */ 301cf7f2e2dSJohn Marino } 302cf7f2e2dSJohn Marino 303cf7f2e2dSJohn Marino static void 304cf7f2e2dSJohn Marino solib_target_solib_create_inferior_hook (int from_tty) 305cf7f2e2dSJohn Marino { 306cf7f2e2dSJohn Marino /* Nothing needed. */ 307cf7f2e2dSJohn Marino } 308cf7f2e2dSJohn Marino 309cf7f2e2dSJohn Marino static void 310cf7f2e2dSJohn Marino solib_target_clear_solib (void) 311cf7f2e2dSJohn Marino { 312cf7f2e2dSJohn Marino /* Nothing needed. */ 313cf7f2e2dSJohn Marino } 314cf7f2e2dSJohn Marino 315cf7f2e2dSJohn Marino static void 316cf7f2e2dSJohn Marino solib_target_free_so (struct so_list *so) 317cf7f2e2dSJohn Marino { 318cf7f2e2dSJohn Marino gdb_assert (so->lm_info->name == NULL); 319cf7f2e2dSJohn Marino xfree (so->lm_info->offsets); 320cf7f2e2dSJohn Marino VEC_free (CORE_ADDR, so->lm_info->segment_bases); 321cf7f2e2dSJohn Marino xfree (so->lm_info); 322cf7f2e2dSJohn Marino } 323cf7f2e2dSJohn Marino 324cf7f2e2dSJohn Marino static void 325cf7f2e2dSJohn Marino solib_target_relocate_section_addresses (struct so_list *so, 326cf7f2e2dSJohn Marino struct target_section *sec) 327cf7f2e2dSJohn Marino { 328cf7f2e2dSJohn Marino int flags = bfd_get_section_flags (sec->bfd, sec->the_bfd_section); 329cf7f2e2dSJohn Marino CORE_ADDR offset; 330cf7f2e2dSJohn Marino 331cf7f2e2dSJohn Marino /* Build the offset table only once per object file. We can not do 332cf7f2e2dSJohn Marino it any earlier, since we need to open the file first. */ 333cf7f2e2dSJohn Marino if (so->lm_info->offsets == NULL) 334cf7f2e2dSJohn Marino { 335cf7f2e2dSJohn Marino int num_sections = bfd_count_sections (so->abfd); 336cf7f2e2dSJohn Marino 337cf7f2e2dSJohn Marino so->lm_info->offsets = xzalloc (SIZEOF_N_SECTION_OFFSETS (num_sections)); 338cf7f2e2dSJohn Marino 339cf7f2e2dSJohn Marino if (so->lm_info->section_bases) 340cf7f2e2dSJohn Marino { 341cf7f2e2dSJohn Marino int i; 342cf7f2e2dSJohn Marino asection *sect; 343cf7f2e2dSJohn Marino int num_section_bases 344cf7f2e2dSJohn Marino = VEC_length (CORE_ADDR, so->lm_info->section_bases); 345cf7f2e2dSJohn Marino int num_alloc_sections = 0; 346cf7f2e2dSJohn Marino 347cf7f2e2dSJohn Marino for (i = 0, sect = so->abfd->sections; 348cf7f2e2dSJohn Marino sect != NULL; 349cf7f2e2dSJohn Marino i++, sect = sect->next) 350cf7f2e2dSJohn Marino if ((bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC)) 351cf7f2e2dSJohn Marino num_alloc_sections++; 352cf7f2e2dSJohn Marino 353cf7f2e2dSJohn Marino if (num_alloc_sections != num_section_bases) 354cf7f2e2dSJohn Marino warning (_("\ 355cf7f2e2dSJohn Marino Could not relocate shared library \"%s\": wrong number of ALLOC sections"), 356cf7f2e2dSJohn Marino so->so_name); 357cf7f2e2dSJohn Marino else 358cf7f2e2dSJohn Marino { 359cf7f2e2dSJohn Marino int bases_index = 0; 360cf7f2e2dSJohn Marino int found_range = 0; 361cf7f2e2dSJohn Marino CORE_ADDR *section_bases; 362cf7f2e2dSJohn Marino 363cf7f2e2dSJohn Marino section_bases = VEC_address (CORE_ADDR, 364cf7f2e2dSJohn Marino so->lm_info->section_bases); 365cf7f2e2dSJohn Marino 366cf7f2e2dSJohn Marino so->addr_low = ~(CORE_ADDR) 0; 367cf7f2e2dSJohn Marino so->addr_high = 0; 368cf7f2e2dSJohn Marino for (i = 0, sect = so->abfd->sections; 369cf7f2e2dSJohn Marino sect != NULL; 370cf7f2e2dSJohn Marino i++, sect = sect->next) 371cf7f2e2dSJohn Marino { 372cf7f2e2dSJohn Marino if (!(bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC)) 373cf7f2e2dSJohn Marino continue; 374cf7f2e2dSJohn Marino if (bfd_section_size (so->abfd, sect) > 0) 375cf7f2e2dSJohn Marino { 376cf7f2e2dSJohn Marino CORE_ADDR low, high; 377cf7f2e2dSJohn Marino 378cf7f2e2dSJohn Marino low = section_bases[i]; 379cf7f2e2dSJohn Marino high = low + bfd_section_size (so->abfd, sect) - 1; 380cf7f2e2dSJohn Marino 381cf7f2e2dSJohn Marino if (low < so->addr_low) 382cf7f2e2dSJohn Marino so->addr_low = low; 383cf7f2e2dSJohn Marino if (high > so->addr_high) 384cf7f2e2dSJohn Marino so->addr_high = high; 385cf7f2e2dSJohn Marino gdb_assert (so->addr_low <= so->addr_high); 386cf7f2e2dSJohn Marino found_range = 1; 387cf7f2e2dSJohn Marino } 388*a45ae5f8SJohn Marino so->lm_info->offsets->offsets[i] 389*a45ae5f8SJohn Marino = section_bases[bases_index]; 390cf7f2e2dSJohn Marino bases_index++; 391cf7f2e2dSJohn Marino } 392cf7f2e2dSJohn Marino if (!found_range) 393cf7f2e2dSJohn Marino so->addr_low = so->addr_high = 0; 394cf7f2e2dSJohn Marino gdb_assert (so->addr_low <= so->addr_high); 395cf7f2e2dSJohn Marino } 396cf7f2e2dSJohn Marino } 397cf7f2e2dSJohn Marino else if (so->lm_info->segment_bases) 398cf7f2e2dSJohn Marino { 399cf7f2e2dSJohn Marino struct symfile_segment_data *data; 400cf7f2e2dSJohn Marino 401cf7f2e2dSJohn Marino data = get_symfile_segment_data (so->abfd); 402cf7f2e2dSJohn Marino if (data == NULL) 403cf7f2e2dSJohn Marino warning (_("\ 404cf7f2e2dSJohn Marino Could not relocate shared library \"%s\": no segments"), so->so_name); 405cf7f2e2dSJohn Marino else 406cf7f2e2dSJohn Marino { 407cf7f2e2dSJohn Marino ULONGEST orig_delta; 408cf7f2e2dSJohn Marino int i; 409cf7f2e2dSJohn Marino int num_bases; 410cf7f2e2dSJohn Marino CORE_ADDR *segment_bases; 411cf7f2e2dSJohn Marino 412cf7f2e2dSJohn Marino num_bases = VEC_length (CORE_ADDR, so->lm_info->segment_bases); 413cf7f2e2dSJohn Marino segment_bases = VEC_address (CORE_ADDR, 414cf7f2e2dSJohn Marino so->lm_info->segment_bases); 415cf7f2e2dSJohn Marino 416cf7f2e2dSJohn Marino if (!symfile_map_offsets_to_segments (so->abfd, data, 417cf7f2e2dSJohn Marino so->lm_info->offsets, 418cf7f2e2dSJohn Marino num_bases, segment_bases)) 419cf7f2e2dSJohn Marino warning (_("\ 420cf7f2e2dSJohn Marino Could not relocate shared library \"%s\": bad offsets"), so->so_name); 421cf7f2e2dSJohn Marino 422cf7f2e2dSJohn Marino /* Find the range of addresses to report for this library in 423cf7f2e2dSJohn Marino "info sharedlibrary". Report any consecutive segments 424cf7f2e2dSJohn Marino which were relocated as a single unit. */ 425cf7f2e2dSJohn Marino gdb_assert (num_bases > 0); 426cf7f2e2dSJohn Marino orig_delta = segment_bases[0] - data->segment_bases[0]; 427cf7f2e2dSJohn Marino 428cf7f2e2dSJohn Marino for (i = 1; i < data->num_segments; i++) 429cf7f2e2dSJohn Marino { 430cf7f2e2dSJohn Marino /* If we have run out of offsets, assume all 431cf7f2e2dSJohn Marino remaining segments have the same offset. */ 432cf7f2e2dSJohn Marino if (i >= num_bases) 433cf7f2e2dSJohn Marino continue; 434cf7f2e2dSJohn Marino 435cf7f2e2dSJohn Marino /* If this segment does not have the same offset, do 436cf7f2e2dSJohn Marino not include it in the library's range. */ 437cf7f2e2dSJohn Marino if (segment_bases[i] - data->segment_bases[i] != orig_delta) 438cf7f2e2dSJohn Marino break; 439cf7f2e2dSJohn Marino } 440cf7f2e2dSJohn Marino 441cf7f2e2dSJohn Marino so->addr_low = segment_bases[0]; 442cf7f2e2dSJohn Marino so->addr_high = (data->segment_bases[i - 1] 443cf7f2e2dSJohn Marino + data->segment_sizes[i - 1] 444cf7f2e2dSJohn Marino + orig_delta); 445cf7f2e2dSJohn Marino gdb_assert (so->addr_low <= so->addr_high); 446cf7f2e2dSJohn Marino 447cf7f2e2dSJohn Marino free_symfile_segment_data (data); 448cf7f2e2dSJohn Marino } 449cf7f2e2dSJohn Marino } 450cf7f2e2dSJohn Marino } 451cf7f2e2dSJohn Marino 452cf7f2e2dSJohn Marino offset = so->lm_info->offsets->offsets[sec->the_bfd_section->index]; 453cf7f2e2dSJohn Marino sec->addr += offset; 454cf7f2e2dSJohn Marino sec->endaddr += offset; 455cf7f2e2dSJohn Marino } 456cf7f2e2dSJohn Marino 457cf7f2e2dSJohn Marino static int 458cf7f2e2dSJohn Marino solib_target_open_symbol_file_object (void *from_ttyp) 459cf7f2e2dSJohn Marino { 460cf7f2e2dSJohn Marino /* We can't locate the main symbol file based on the target's 461cf7f2e2dSJohn Marino knowledge; the user has to specify it. */ 462cf7f2e2dSJohn Marino return 0; 463cf7f2e2dSJohn Marino } 464cf7f2e2dSJohn Marino 465cf7f2e2dSJohn Marino static int 466cf7f2e2dSJohn Marino solib_target_in_dynsym_resolve_code (CORE_ADDR pc) 467cf7f2e2dSJohn Marino { 468cf7f2e2dSJohn Marino /* We don't have a range of addresses for the dynamic linker; there 469cf7f2e2dSJohn Marino may not be one in the program's address space. So only report 470cf7f2e2dSJohn Marino PLT entries (which may be import stubs). */ 471cf7f2e2dSJohn Marino return in_plt_section (pc, NULL); 472cf7f2e2dSJohn Marino } 473cf7f2e2dSJohn Marino 474cf7f2e2dSJohn Marino struct target_so_ops solib_target_so_ops; 475cf7f2e2dSJohn Marino 476*a45ae5f8SJohn Marino /* -Wmissing-prototypes */ 477*a45ae5f8SJohn Marino extern initialize_file_ftype _initialize_solib_target; 478cf7f2e2dSJohn Marino 479cf7f2e2dSJohn Marino void 480cf7f2e2dSJohn Marino _initialize_solib_target (void) 481cf7f2e2dSJohn Marino { 482cf7f2e2dSJohn Marino solib_target_so_ops.relocate_section_addresses 483cf7f2e2dSJohn Marino = solib_target_relocate_section_addresses; 484cf7f2e2dSJohn Marino solib_target_so_ops.free_so = solib_target_free_so; 485cf7f2e2dSJohn Marino solib_target_so_ops.clear_solib = solib_target_clear_solib; 486cf7f2e2dSJohn Marino solib_target_so_ops.solib_create_inferior_hook 487cf7f2e2dSJohn Marino = solib_target_solib_create_inferior_hook; 488cf7f2e2dSJohn Marino solib_target_so_ops.special_symbol_handling 489cf7f2e2dSJohn Marino = solib_target_special_symbol_handling; 490cf7f2e2dSJohn Marino solib_target_so_ops.current_sos = solib_target_current_sos; 491cf7f2e2dSJohn Marino solib_target_so_ops.open_symbol_file_object 492cf7f2e2dSJohn Marino = solib_target_open_symbol_file_object; 493cf7f2e2dSJohn Marino solib_target_so_ops.in_dynsym_resolve_code 494cf7f2e2dSJohn Marino = solib_target_in_dynsym_resolve_code; 495cf7f2e2dSJohn Marino solib_target_so_ops.bfd_open = solib_bfd_open; 496cf7f2e2dSJohn Marino 497cf7f2e2dSJohn Marino /* Set current_target_so_ops to solib_target_so_ops if not already 498cf7f2e2dSJohn Marino set. */ 499cf7f2e2dSJohn Marino if (current_target_so_ops == 0) 500cf7f2e2dSJohn Marino current_target_so_ops = &solib_target_so_ops; 501cf7f2e2dSJohn Marino } 502