1 /* Copyright (C) 2013-2016 Free Software Foundation, Inc. 2 3 This file is part of GDB. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 18 #include "defs.h" 19 #include "solib-aix.h" 20 #include "solist.h" 21 #include "inferior.h" 22 #include "gdb_bfd.h" 23 #include "gdbcore.h" 24 #include "objfiles.h" 25 #include "symtab.h" 26 #include "xcoffread.h" 27 #include "observer.h" 28 #include "gdbcmd.h" 29 30 /* Variable controlling the output of the debugging traces for 31 this module. */ 32 static int solib_aix_debug; 33 34 /* Our private data in struct so_list. */ 35 36 struct lm_info 37 { 38 /* The name of the file mapped by the loader. Apart from the entry 39 for the main executable, this is usually a shared library (which, 40 on AIX, is an archive library file, created using the "ar" 41 command). */ 42 char *filename; 43 44 /* The name of the shared object file with the actual dynamic 45 loading dependency. This may be NULL (Eg. main executable). */ 46 char *member_name; 47 48 /* The address in inferior memory where the text section got mapped. */ 49 CORE_ADDR text_addr; 50 51 /* The size of the text section, obtained via the loader data. */ 52 ULONGEST text_size; 53 54 /* The address in inferior memory where the data section got mapped. */ 55 CORE_ADDR data_addr; 56 57 /* The size of the data section, obtained via the loader data. */ 58 ULONGEST data_size; 59 }; 60 61 typedef struct lm_info *lm_info_p; 62 DEF_VEC_P(lm_info_p); 63 64 /* Return a deep copy of the given struct lm_info object. */ 65 66 static struct lm_info * 67 solib_aix_new_lm_info (struct lm_info *info) 68 { 69 struct lm_info *result = XNEW (struct lm_info); 70 71 memcpy (result, info, sizeof (struct lm_info)); 72 result->filename = xstrdup (info->filename); 73 if (info->member_name != NULL) 74 result->member_name = xstrdup (info->member_name); 75 76 return result; 77 } 78 79 /* Free the memory allocated for the given lm_info. */ 80 81 static void 82 solib_aix_xfree_lm_info (struct lm_info *info) 83 { 84 xfree (info->filename); 85 xfree (info->member_name); 86 xfree (info); 87 } 88 89 /* This module's per-inferior data. */ 90 91 struct solib_aix_inferior_data 92 { 93 /* The list of shared libraries. NULL if not computed yet. 94 95 Note that the first element of this list is always the main 96 executable, which is not technically a shared library. But 97 we need that information to perform its relocation, and 98 the same principles applied to shared libraries also apply 99 to the main executable. So it's simpler to keep it as part 100 of this list. */ 101 VEC (lm_info_p) *library_list; 102 }; 103 104 /* Key to our per-inferior data. */ 105 static const struct inferior_data *solib_aix_inferior_data_handle; 106 107 /* Return this module's data for the given inferior. 108 If none is found, add a zero'ed one now. */ 109 110 static struct solib_aix_inferior_data * 111 get_solib_aix_inferior_data (struct inferior *inf) 112 { 113 struct solib_aix_inferior_data *data; 114 115 data = ((struct solib_aix_inferior_data *) 116 inferior_data (inf, solib_aix_inferior_data_handle)); 117 if (data == NULL) 118 { 119 data = XCNEW (struct solib_aix_inferior_data); 120 set_inferior_data (inf, solib_aix_inferior_data_handle, data); 121 } 122 123 return data; 124 } 125 126 #if !defined(HAVE_LIBEXPAT) 127 128 /* Dummy implementation if XML support is not compiled in. */ 129 130 static VEC (lm_info_p) * 131 solib_aix_parse_libraries (const char *library) 132 { 133 static int have_warned; 134 135 if (!have_warned) 136 { 137 have_warned = 1; 138 warning (_("Can not parse XML library list; XML support was disabled " 139 "at compile time")); 140 } 141 142 return NULL; 143 } 144 145 /* Dummy implementation if XML support is not compiled in. */ 146 147 static void 148 solib_aix_free_library_list (void *p) 149 { 150 } 151 152 #else /* HAVE_LIBEXPAT */ 153 154 #include "xml-support.h" 155 156 /* Handle the start of a <library> element. */ 157 158 static void 159 library_list_start_library (struct gdb_xml_parser *parser, 160 const struct gdb_xml_element *element, 161 void *user_data, 162 VEC (gdb_xml_value_s) *attributes) 163 { 164 VEC (lm_info_p) **list = (VEC (lm_info_p) **) user_data; 165 struct lm_info *item = XCNEW (struct lm_info); 166 struct gdb_xml_value *attr; 167 168 attr = xml_find_attribute (attributes, "name"); 169 item->filename = xstrdup ((const char *) attr->value); 170 171 attr = xml_find_attribute (attributes, "member"); 172 if (attr != NULL) 173 item->member_name = xstrdup ((const char *) attr->value); 174 175 attr = xml_find_attribute (attributes, "text_addr"); 176 item->text_addr = * (ULONGEST *) attr->value; 177 178 attr = xml_find_attribute (attributes, "text_size"); 179 item->text_size = * (ULONGEST *) attr->value; 180 181 attr = xml_find_attribute (attributes, "data_addr"); 182 item->data_addr = * (ULONGEST *) attr->value; 183 184 attr = xml_find_attribute (attributes, "data_size"); 185 item->data_size = * (ULONGEST *) attr->value; 186 187 VEC_safe_push (lm_info_p, *list, item); 188 } 189 190 /* Handle the start of a <library-list-aix> element. */ 191 192 static void 193 library_list_start_list (struct gdb_xml_parser *parser, 194 const struct gdb_xml_element *element, 195 void *user_data, VEC (gdb_xml_value_s) *attributes) 196 { 197 char *version = (char *) xml_find_attribute (attributes, "version")->value; 198 199 if (strcmp (version, "1.0") != 0) 200 gdb_xml_error (parser, 201 _("Library list has unsupported version \"%s\""), 202 version); 203 } 204 205 /* Discard the constructed library list. */ 206 207 static void 208 solib_aix_free_library_list (void *p) 209 { 210 VEC (lm_info_p) **result = (VEC (lm_info_p) **) p; 211 struct lm_info *info; 212 int ix; 213 214 if (solib_aix_debug) 215 fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_library_list\n"); 216 217 for (ix = 0; VEC_iterate (lm_info_p, *result, ix, info); ix++) 218 solib_aix_xfree_lm_info (info); 219 VEC_free (lm_info_p, *result); 220 *result = NULL; 221 } 222 223 /* The allowed elements and attributes for an AIX library list 224 described in XML format. The root element is a <library-list-aix>. */ 225 226 static const struct gdb_xml_attribute library_attributes[] = 227 { 228 { "name", GDB_XML_AF_NONE, NULL, NULL }, 229 { "member", GDB_XML_AF_OPTIONAL, NULL, NULL }, 230 { "text_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 231 { "text_size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 232 { "data_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 233 { "data_size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 234 { NULL, GDB_XML_AF_NONE, NULL, NULL } 235 }; 236 237 static const struct gdb_xml_element library_list_children[] = 238 { 239 { "library", library_attributes, NULL, 240 GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL, 241 library_list_start_library, NULL}, 242 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 243 }; 244 245 static const struct gdb_xml_attribute library_list_attributes[] = 246 { 247 { "version", GDB_XML_AF_NONE, NULL, NULL }, 248 { NULL, GDB_XML_AF_NONE, NULL, NULL } 249 }; 250 251 static const struct gdb_xml_element library_list_elements[] = 252 { 253 { "library-list-aix", library_list_attributes, library_list_children, 254 GDB_XML_EF_NONE, library_list_start_list, NULL }, 255 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 256 }; 257 258 /* Parse LIBRARY, a string containing the loader info in XML format, 259 and return an lm_info_p vector. 260 261 Return NULL if the parsing failed. */ 262 263 static VEC (lm_info_p) * 264 solib_aix_parse_libraries (const char *library) 265 { 266 VEC (lm_info_p) *result = NULL; 267 struct cleanup *back_to = make_cleanup (solib_aix_free_library_list, 268 &result); 269 270 if (gdb_xml_parse_quick (_("aix library list"), "library-list-aix.dtd", 271 library_list_elements, library, &result) == 0) 272 { 273 /* Parsed successfully, keep the result. */ 274 discard_cleanups (back_to); 275 return result; 276 } 277 278 do_cleanups (back_to); 279 return NULL; 280 } 281 282 #endif /* HAVE_LIBEXPAT */ 283 284 /* Return the loader info for the given inferior (INF), or NULL if 285 the list could not be computed. 286 287 Cache the result in per-inferior data, so as to avoid recomputing it 288 each time this function is called. 289 290 If an error occurs while computing this list, and WARNING_MSG 291 is not NULL, then print a warning including WARNING_MSG and 292 a description of the error. */ 293 294 static VEC (lm_info_p) * 295 solib_aix_get_library_list (struct inferior *inf, const char *warning_msg) 296 { 297 struct solib_aix_inferior_data *data; 298 char *library_document; 299 struct cleanup *cleanup; 300 301 /* If already computed, return the cached value. */ 302 data = get_solib_aix_inferior_data (inf); 303 if (data->library_list != NULL) 304 return data->library_list; 305 306 library_document = target_read_stralloc (¤t_target, 307 TARGET_OBJECT_LIBRARIES_AIX, 308 NULL); 309 if (library_document == NULL && warning_msg != NULL) 310 { 311 warning (_("%s (failed to read TARGET_OBJECT_LIBRARIES_AIX)"), 312 warning_msg); 313 return NULL; 314 } 315 cleanup = make_cleanup (xfree, library_document); 316 317 if (solib_aix_debug) 318 fprintf_unfiltered (gdb_stdlog, 319 "DEBUG: TARGET_OBJECT_LIBRARIES_AIX = \n%s\n", 320 library_document); 321 322 data->library_list = solib_aix_parse_libraries (library_document); 323 if (data->library_list == NULL && warning_msg != NULL) 324 { 325 warning (_("%s (missing XML support?)"), warning_msg); 326 do_cleanups (cleanup); 327 return NULL; 328 } 329 330 do_cleanups (cleanup); 331 return data->library_list; 332 } 333 334 /* If the .bss section's VMA is set to an address located before 335 the end of the .data section, causing the two sections to overlap, 336 return the overlap in bytes. Otherwise, return zero. 337 338 Motivation: 339 340 The GNU linker sometimes sets the start address of the .bss session 341 before the end of the .data section, making the 2 sections overlap. 342 The loader appears to handle this situation gracefully, by simply 343 loading the bss section right after the end of the .data section. 344 345 This means that the .data and the .bss sections are sometimes 346 no longer relocated by the same amount. The problem is that 347 the ldinfo data does not contain any information regarding 348 the relocation of the .bss section, assuming that it would be 349 identical to the information provided for the .data section 350 (this is what would normally happen if the program was linked 351 correctly). 352 353 GDB therefore needs to detect those cases, and make the corresponding 354 adjustment to the .bss section offset computed from the ldinfo data 355 when necessary. This function returns the adjustment amount (or 356 zero when no adjustment is needed). */ 357 358 static CORE_ADDR 359 solib_aix_bss_data_overlap (bfd *abfd) 360 { 361 struct bfd_section *data_sect, *bss_sect; 362 363 data_sect = bfd_get_section_by_name (abfd, ".data"); 364 if (data_sect == NULL) 365 return 0; /* No overlap possible. */ 366 367 bss_sect = bfd_get_section_by_name (abfd, ".bss"); 368 if (bss_sect == NULL) 369 return 0; /* No overlap possible. */ 370 371 /* Assume the problem only occurs with linkers that place the .bss 372 section after the .data section (the problem has only been 373 observed when using the GNU linker, and the default linker 374 script always places the .data and .bss sections in that order). */ 375 if (bfd_section_vma (abfd, bss_sect) 376 < bfd_section_vma (abfd, data_sect)) 377 return 0; 378 379 if (bfd_section_vma (abfd, bss_sect) 380 < bfd_section_vma (abfd, data_sect) + bfd_get_section_size (data_sect)) 381 return ((bfd_section_vma (abfd, data_sect) 382 + bfd_get_section_size (data_sect)) 383 - bfd_section_vma (abfd, bss_sect)); 384 385 return 0; 386 } 387 388 /* Implement the "relocate_section_addresses" target_so_ops method. */ 389 390 static void 391 solib_aix_relocate_section_addresses (struct so_list *so, 392 struct target_section *sec) 393 { 394 struct bfd_section *bfd_sect = sec->the_bfd_section; 395 bfd *abfd = bfd_sect->owner; 396 const char *section_name = bfd_section_name (abfd, bfd_sect); 397 struct lm_info *info = so->lm_info; 398 399 if (strcmp (section_name, ".text") == 0) 400 { 401 sec->addr = info->text_addr; 402 sec->endaddr = sec->addr + info->text_size; 403 404 /* The text address given to us by the loader contains 405 XCOFF headers, so we need to adjust by this much. */ 406 sec->addr += bfd_sect->filepos; 407 } 408 else if (strcmp (section_name, ".data") == 0) 409 { 410 sec->addr = info->data_addr; 411 sec->endaddr = sec->addr + info->data_size; 412 } 413 else if (strcmp (section_name, ".bss") == 0) 414 { 415 /* The information provided by the loader does not include 416 the address of the .bss section, but we know that it gets 417 relocated by the same offset as the .data section. So, 418 compute the relocation offset for the .data section, and 419 apply it to the .bss section as well. If the .data section 420 is not defined (which seems highly unlikely), do our best 421 by assuming no relocation. */ 422 struct bfd_section *data_sect 423 = bfd_get_section_by_name (abfd, ".data"); 424 CORE_ADDR data_offset = 0; 425 426 if (data_sect != NULL) 427 data_offset = info->data_addr - bfd_section_vma (abfd, data_sect); 428 429 sec->addr = bfd_section_vma (abfd, bfd_sect) + data_offset; 430 sec->addr += solib_aix_bss_data_overlap (abfd); 431 sec->endaddr = sec->addr + bfd_section_size (abfd, bfd_sect); 432 } 433 else 434 { 435 /* All other sections should not be relocated. */ 436 sec->addr = bfd_section_vma (abfd, bfd_sect); 437 sec->endaddr = sec->addr + bfd_section_size (abfd, bfd_sect); 438 } 439 } 440 441 /* Implement the "free_so" target_so_ops method. */ 442 443 static void 444 solib_aix_free_so (struct so_list *so) 445 { 446 if (solib_aix_debug) 447 fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_so (%s)\n", 448 so->so_name); 449 solib_aix_xfree_lm_info (so->lm_info); 450 } 451 452 /* Implement the "clear_solib" target_so_ops method. */ 453 454 static void 455 solib_aix_clear_solib (void) 456 { 457 /* Nothing needed. */ 458 } 459 460 /* Compute and return the OBJFILE's section_offset array, using 461 the associated loader info (INFO). 462 463 The resulting array is computed on the heap and must be 464 deallocated after use. */ 465 466 static struct section_offsets * 467 solib_aix_get_section_offsets (struct objfile *objfile, 468 struct lm_info *info) 469 { 470 struct section_offsets *offsets; 471 bfd *abfd = objfile->obfd; 472 473 offsets = XCNEWVEC (struct section_offsets, objfile->num_sections); 474 475 /* .text */ 476 477 if (objfile->sect_index_text != -1) 478 { 479 struct bfd_section *sect 480 = objfile->sections[objfile->sect_index_text].the_bfd_section; 481 482 offsets->offsets[objfile->sect_index_text] 483 = info->text_addr + sect->filepos - bfd_section_vma (abfd, sect); 484 } 485 486 /* .data */ 487 488 if (objfile->sect_index_data != -1) 489 { 490 struct bfd_section *sect 491 = objfile->sections[objfile->sect_index_data].the_bfd_section; 492 493 offsets->offsets[objfile->sect_index_data] 494 = info->data_addr - bfd_section_vma (abfd, sect); 495 } 496 497 /* .bss 498 499 The offset of the .bss section should be identical to the offset 500 of the .data section. If no .data section (which seems hard to 501 believe it is possible), assume it is zero. */ 502 503 if (objfile->sect_index_bss != -1 504 && objfile->sect_index_data != -1) 505 { 506 offsets->offsets[objfile->sect_index_bss] 507 = (offsets->offsets[objfile->sect_index_data] 508 + solib_aix_bss_data_overlap (abfd)); 509 } 510 511 /* All other sections should not need relocation. */ 512 513 return offsets; 514 } 515 516 /* Implement the "solib_create_inferior_hook" target_so_ops method. */ 517 518 static void 519 solib_aix_solib_create_inferior_hook (int from_tty) 520 { 521 const char *warning_msg = "unable to relocate main executable"; 522 VEC (lm_info_p) *library_list; 523 struct lm_info *exec_info; 524 525 /* We need to relocate the main executable... */ 526 527 library_list = solib_aix_get_library_list (current_inferior (), 528 warning_msg); 529 if (library_list == NULL) 530 return; /* Warning already printed. */ 531 532 if (VEC_length (lm_info_p, library_list) < 1) 533 { 534 warning (_("unable to relocate main executable (no info from loader)")); 535 return; 536 } 537 538 exec_info = VEC_index (lm_info_p, library_list, 0); 539 540 if (symfile_objfile != NULL) 541 { 542 struct section_offsets *offsets 543 = solib_aix_get_section_offsets (symfile_objfile, exec_info); 544 struct cleanup *cleanup = make_cleanup (xfree, offsets); 545 546 objfile_relocate (symfile_objfile, offsets); 547 do_cleanups (cleanup); 548 } 549 } 550 551 /* Implement the "special_symbol_handling" target_so_ops method. */ 552 553 static void 554 solib_aix_special_symbol_handling (void) 555 { 556 /* Nothing needed. */ 557 } 558 559 /* Implement the "current_sos" target_so_ops method. */ 560 561 static struct so_list * 562 solib_aix_current_sos (void) 563 { 564 struct so_list *start = NULL, *last = NULL; 565 VEC (lm_info_p) *library_list; 566 struct lm_info *info; 567 int ix; 568 569 library_list = solib_aix_get_library_list (current_inferior (), NULL); 570 if (library_list == NULL) 571 return NULL; 572 573 /* Build a struct so_list for each entry on the list. 574 We skip the first entry, since this is the entry corresponding 575 to the main executable, not a shared library. */ 576 for (ix = 1; VEC_iterate (lm_info_p, library_list, ix, info); ix++) 577 { 578 struct so_list *new_solib = XCNEW (struct so_list); 579 char *so_name; 580 581 if (info->member_name == NULL) 582 { 583 /* INFO->FILENAME is probably not an archive, but rather 584 a shared object. Unusual, but it should be possible 585 to link a program against a shared object directory, 586 without having to put it in an archive first. */ 587 so_name = xstrdup (info->filename); 588 } 589 else 590 { 591 /* This is the usual case on AIX, where the shared object 592 is a member of an archive. Create a synthetic so_name 593 that follows the same convention as AIX's ldd tool 594 (Eg: "/lib/libc.a(shr.o)"). */ 595 so_name = xstrprintf ("%s(%s)", info->filename, info->member_name); 596 } 597 strncpy (new_solib->so_original_name, so_name, 598 SO_NAME_MAX_PATH_SIZE - 1); 599 new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; 600 memcpy (new_solib->so_name, new_solib->so_original_name, 601 SO_NAME_MAX_PATH_SIZE); 602 new_solib->lm_info = solib_aix_new_lm_info (info); 603 604 /* Add it to the list. */ 605 if (!start) 606 last = start = new_solib; 607 else 608 { 609 last->next = new_solib; 610 last = new_solib; 611 } 612 } 613 614 return start; 615 } 616 617 /* Implement the "open_symbol_file_object" target_so_ops method. */ 618 619 static int 620 solib_aix_open_symbol_file_object (void *from_ttyp) 621 { 622 return 0; 623 } 624 625 /* Implement the "in_dynsym_resolve_code" target_so_ops method. */ 626 627 static int 628 solib_aix_in_dynsym_resolve_code (CORE_ADDR pc) 629 { 630 return 0; 631 } 632 633 /* Implement the "bfd_open" target_so_ops method. */ 634 635 static bfd * 636 solib_aix_bfd_open (char *pathname) 637 { 638 /* The pathname is actually a synthetic filename with the following 639 form: "/path/to/sharedlib(member.o)" (double-quotes excluded). 640 split this into archive name and member name. 641 642 FIXME: This is a little hacky. Perhaps we should provide access 643 to the solib's lm_info here? */ 644 const int path_len = strlen (pathname); 645 char *sep; 646 char *filename; 647 int filename_len; 648 char *member_name; 649 bfd *archive_bfd, *object_bfd; 650 struct cleanup *cleanup; 651 652 if (pathname[path_len - 1] != ')') 653 return solib_bfd_open (pathname); 654 655 /* Search for the associated parens. */ 656 sep = strrchr (pathname, '('); 657 if (sep == NULL) 658 { 659 /* Should never happen, but recover as best as we can (trying 660 to open pathname without decoding, possibly leading to 661 a failure), rather than triggering an assert failure). */ 662 warning (_("missing '(' in shared object pathname: %s"), pathname); 663 return solib_bfd_open (pathname); 664 } 665 filename_len = sep - pathname; 666 667 filename = xstrprintf ("%.*s", filename_len, pathname); 668 cleanup = make_cleanup (xfree, filename); 669 member_name = xstrprintf ("%.*s", path_len - filename_len - 2, sep + 1); 670 make_cleanup (xfree, member_name); 671 672 archive_bfd = gdb_bfd_open (filename, gnutarget, -1); 673 if (archive_bfd == NULL) 674 { 675 warning (_("Could not open `%s' as an executable file: %s"), 676 filename, bfd_errmsg (bfd_get_error ())); 677 do_cleanups (cleanup); 678 return NULL; 679 } 680 681 if (bfd_check_format (archive_bfd, bfd_object)) 682 { 683 do_cleanups (cleanup); 684 return archive_bfd; 685 } 686 687 if (! bfd_check_format (archive_bfd, bfd_archive)) 688 { 689 warning (_("\"%s\": not in executable format: %s."), 690 filename, bfd_errmsg (bfd_get_error ())); 691 gdb_bfd_unref (archive_bfd); 692 do_cleanups (cleanup); 693 return NULL; 694 } 695 696 object_bfd = gdb_bfd_openr_next_archived_file (archive_bfd, NULL); 697 while (object_bfd != NULL) 698 { 699 bfd *next; 700 701 if (strcmp (member_name, object_bfd->filename) == 0) 702 break; 703 704 next = gdb_bfd_openr_next_archived_file (archive_bfd, object_bfd); 705 gdb_bfd_unref (object_bfd); 706 object_bfd = next; 707 } 708 709 if (object_bfd == NULL) 710 { 711 warning (_("\"%s\": member \"%s\" missing."), filename, member_name); 712 gdb_bfd_unref (archive_bfd); 713 do_cleanups (cleanup); 714 return NULL; 715 } 716 717 if (! bfd_check_format (object_bfd, bfd_object)) 718 { 719 warning (_("%s(%s): not in object format: %s."), 720 filename, member_name, bfd_errmsg (bfd_get_error ())); 721 gdb_bfd_unref (archive_bfd); 722 gdb_bfd_unref (object_bfd); 723 do_cleanups (cleanup); 724 return NULL; 725 } 726 727 /* Override the returned bfd's name with our synthetic name in order 728 to allow commands listing all shared libraries to display that 729 synthetic name. Otherwise, we would only be displaying the name 730 of the archive member object. */ 731 xfree (bfd_get_filename (object_bfd)); 732 object_bfd->filename = xstrdup (pathname); 733 734 gdb_bfd_unref (archive_bfd); 735 do_cleanups (cleanup); 736 return object_bfd; 737 } 738 739 /* Return the obj_section corresponding to OBJFILE's data section, 740 or NULL if not found. */ 741 /* FIXME: Define in a more general location? */ 742 743 static struct obj_section * 744 data_obj_section_from_objfile (struct objfile *objfile) 745 { 746 struct obj_section *osect; 747 748 ALL_OBJFILE_OSECTIONS (objfile, osect) 749 if (strcmp (bfd_section_name (objfile->obfd, osect->the_bfd_section), 750 ".data") == 0) 751 return osect; 752 753 return NULL; 754 } 755 756 /* Return the TOC value corresponding to the given PC address, 757 or raise an error if the value could not be determined. */ 758 759 CORE_ADDR 760 solib_aix_get_toc_value (CORE_ADDR pc) 761 { 762 struct obj_section *pc_osect = find_pc_section (pc); 763 struct obj_section *data_osect; 764 CORE_ADDR result; 765 766 if (pc_osect == NULL) 767 error (_("unable to find TOC entry for pc %s " 768 "(no section contains this PC)"), 769 core_addr_to_string (pc)); 770 771 data_osect = data_obj_section_from_objfile (pc_osect->objfile); 772 if (data_osect == NULL) 773 error (_("unable to find TOC entry for pc %s " 774 "(%s has no data section)"), 775 core_addr_to_string (pc), objfile_name (pc_osect->objfile)); 776 777 result = (obj_section_addr (data_osect) 778 + xcoff_get_toc_offset (pc_osect->objfile)); 779 if (solib_aix_debug) 780 fprintf_unfiltered (gdb_stdlog, 781 "DEBUG: solib_aix_get_toc_value (pc=%s) -> %s\n", 782 core_addr_to_string (pc), 783 core_addr_to_string (result)); 784 785 return result; 786 } 787 788 /* This module's normal_stop observer. */ 789 790 static void 791 solib_aix_normal_stop_observer (struct bpstats *unused_1, int unused_2) 792 { 793 struct solib_aix_inferior_data *data 794 = get_solib_aix_inferior_data (current_inferior ()); 795 796 /* The inferior execution has been resumed, and it just stopped 797 again. This means that the list of shared libraries may have 798 evolved. Reset our cached value. */ 799 solib_aix_free_library_list (&data->library_list); 800 } 801 802 /* Implements the "show debug aix-solib" command. */ 803 804 static void 805 show_solib_aix_debug (struct ui_file *file, int from_tty, 806 struct cmd_list_element *c, const char *value) 807 { 808 fprintf_filtered (file, _("solib-aix debugging is %s.\n"), value); 809 } 810 811 /* The target_so_ops for AIX targets. */ 812 struct target_so_ops solib_aix_so_ops; 813 814 /* -Wmissing-prototypes */ 815 extern initialize_file_ftype _initialize_solib_aix; 816 817 void 818 _initialize_solib_aix (void) 819 { 820 solib_aix_so_ops.relocate_section_addresses 821 = solib_aix_relocate_section_addresses; 822 solib_aix_so_ops.free_so = solib_aix_free_so; 823 solib_aix_so_ops.clear_solib = solib_aix_clear_solib; 824 solib_aix_so_ops.solib_create_inferior_hook 825 = solib_aix_solib_create_inferior_hook; 826 solib_aix_so_ops.special_symbol_handling 827 = solib_aix_special_symbol_handling; 828 solib_aix_so_ops.current_sos = solib_aix_current_sos; 829 solib_aix_so_ops.open_symbol_file_object 830 = solib_aix_open_symbol_file_object; 831 solib_aix_so_ops.in_dynsym_resolve_code 832 = solib_aix_in_dynsym_resolve_code; 833 solib_aix_so_ops.bfd_open = solib_aix_bfd_open; 834 835 solib_aix_inferior_data_handle = register_inferior_data (); 836 837 observer_attach_normal_stop (solib_aix_normal_stop_observer); 838 839 /* Debug this file's internals. */ 840 add_setshow_boolean_cmd ("aix-solib", class_maintenance, 841 &solib_aix_debug, _("\ 842 Control the debugging traces for the solib-aix module."), _("\ 843 Show whether solib-aix debugging traces are enabled."), _("\ 844 When on, solib-aix debugging traces are enabled."), 845 NULL, 846 show_solib_aix_debug, 847 &setdebuglist, &showdebuglist); 848 } 849