GDB (API)
|
00001 /* Copyright (C) 2013 Free Software Foundation, Inc. 00002 00003 This file is part of GDB. 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 3 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00017 00018 #include "defs.h" 00019 #include "solib-aix.h" 00020 #include "solist.h" 00021 #include "inferior.h" 00022 #include "gdb_bfd.h" 00023 #include "gdbcore.h" 00024 #include "objfiles.h" 00025 #include "symtab.h" 00026 #include "xcoffread.h" 00027 #include "observer.h" 00028 #include "gdbcmd.h" 00029 00030 /* Variable controlling the output of the debugging traces for 00031 this module. */ 00032 static int solib_aix_debug; 00033 00034 /* Our private data in struct so_list. */ 00035 00036 struct lm_info 00037 { 00038 /* The name of the file mapped by the loader. Apart from the entry 00039 for the main executable, this is usually a shared library (which, 00040 on AIX, is an archive library file, created using the "ar" 00041 command). */ 00042 char *filename; 00043 00044 /* The name of the shared object file with the actual dynamic 00045 loading dependency. This may be NULL (Eg. main executable). */ 00046 char *member_name; 00047 00048 /* The address in inferior memory where the text section got mapped. */ 00049 CORE_ADDR text_addr; 00050 00051 /* The size of the text section, obtained via the loader data. */ 00052 ULONGEST text_size; 00053 00054 /* The address in inferior memory where the data section got mapped. */ 00055 CORE_ADDR data_addr; 00056 00057 /* The size of the data section, obtained via the loader data. */ 00058 ULONGEST data_size; 00059 }; 00060 00061 typedef struct lm_info *lm_info_p; 00062 DEF_VEC_P(lm_info_p); 00063 00064 /* Return a deep copy of the given struct lm_info object. */ 00065 00066 static struct lm_info * 00067 solib_aix_new_lm_info (struct lm_info *info) 00068 { 00069 struct lm_info *result = xmalloc (sizeof (struct lm_info)); 00070 00071 memcpy (result, info, sizeof (struct lm_info)); 00072 result->filename = xstrdup (info->filename); 00073 if (info->member_name != NULL) 00074 result->member_name = xstrdup (info->member_name); 00075 00076 return result; 00077 } 00078 00079 /* Free the memory allocated for the given lm_info. */ 00080 00081 static void 00082 solib_aix_xfree_lm_info (struct lm_info *info) 00083 { 00084 xfree (info->filename); 00085 xfree (info->member_name); 00086 xfree (info); 00087 } 00088 00089 /* This module's per-inferior data. */ 00090 00091 struct solib_aix_inferior_data 00092 { 00093 /* The list of shared libraries. NULL if not computed yet. 00094 00095 Note that the first element of this list is always the main 00096 executable, which is not technically a shared library. But 00097 we need that information to perform its relocation, and 00098 the same principles applied to shared libraries also apply 00099 to the main executable. So it's simpler to keep it as part 00100 of this list. */ 00101 VEC (lm_info_p) *library_list; 00102 }; 00103 00104 /* Key to our per-inferior data. */ 00105 static const struct inferior_data *solib_aix_inferior_data_handle; 00106 00107 /* Return this module's data for the given inferior. 00108 If none is found, add a zero'ed one now. */ 00109 00110 static struct solib_aix_inferior_data * 00111 get_solib_aix_inferior_data (struct inferior *inf) 00112 { 00113 struct solib_aix_inferior_data *data; 00114 00115 data = inferior_data (inf, solib_aix_inferior_data_handle); 00116 if (data == NULL) 00117 { 00118 data = XZALLOC (struct solib_aix_inferior_data); 00119 set_inferior_data (inf, solib_aix_inferior_data_handle, data); 00120 } 00121 00122 return data; 00123 } 00124 00125 #if !defined(HAVE_LIBEXPAT) 00126 00127 /* Dummy implementation if XML support is not compiled in. */ 00128 00129 static VEC (lm_info_p) * 00130 solib_aix_parse_libraries (const char *library) 00131 { 00132 static int have_warned; 00133 00134 if (!have_warned) 00135 { 00136 have_warned = 1; 00137 warning (_("Can not parse XML library list; XML support was disabled " 00138 "at compile time")); 00139 } 00140 00141 return NULL; 00142 } 00143 00144 /* Dummy implementation if XML support is not compiled in. */ 00145 00146 static void 00147 solib_aix_free_library_list (void *p) 00148 { 00149 } 00150 00151 #else /* HAVE_LIBEXPAT */ 00152 00153 #include "xml-support.h" 00154 00155 /* Handle the start of a <library> element. */ 00156 00157 static void 00158 library_list_start_library (struct gdb_xml_parser *parser, 00159 const struct gdb_xml_element *element, 00160 void *user_data, 00161 VEC (gdb_xml_value_s) *attributes) 00162 { 00163 VEC (lm_info_p) **list = user_data; 00164 struct lm_info *item = XZALLOC (struct lm_info); 00165 struct gdb_xml_value *attr; 00166 00167 attr = xml_find_attribute (attributes, "name"); 00168 item->filename = xstrdup (attr->value); 00169 00170 attr = xml_find_attribute (attributes, "member"); 00171 if (attr != NULL) 00172 item->member_name = xstrdup (attr->value); 00173 00174 attr = xml_find_attribute (attributes, "text_addr"); 00175 item->text_addr = * (ULONGEST *) attr->value; 00176 00177 attr = xml_find_attribute (attributes, "text_size"); 00178 item->text_size = * (ULONGEST *) attr->value; 00179 00180 attr = xml_find_attribute (attributes, "data_addr"); 00181 item->data_addr = * (ULONGEST *) attr->value; 00182 00183 attr = xml_find_attribute (attributes, "data_size"); 00184 item->data_size = * (ULONGEST *) attr->value; 00185 00186 VEC_safe_push (lm_info_p, *list, item); 00187 } 00188 00189 /* Handle the start of a <library-list-aix> element. */ 00190 00191 static void 00192 library_list_start_list (struct gdb_xml_parser *parser, 00193 const struct gdb_xml_element *element, 00194 void *user_data, VEC (gdb_xml_value_s) *attributes) 00195 { 00196 char *version = xml_find_attribute (attributes, "version")->value; 00197 00198 if (strcmp (version, "1.0") != 0) 00199 gdb_xml_error (parser, 00200 _("Library list has unsupported version \"%s\""), 00201 version); 00202 } 00203 00204 /* Discard the constructed library list. */ 00205 00206 static void 00207 solib_aix_free_library_list (void *p) 00208 { 00209 VEC (lm_info_p) **result = p; 00210 struct lm_info *info; 00211 int ix; 00212 00213 if (solib_aix_debug) 00214 fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_library_list\n"); 00215 00216 for (ix = 0; VEC_iterate (lm_info_p, *result, ix, info); ix++) 00217 solib_aix_xfree_lm_info (info); 00218 VEC_free (lm_info_p, *result); 00219 *result = NULL; 00220 } 00221 00222 /* The allowed elements and attributes for an AIX library list 00223 described in XML format. The root element is a <library-list-aix>. */ 00224 00225 static const struct gdb_xml_attribute library_attributes[] = 00226 { 00227 { "name", GDB_XML_AF_NONE, NULL, NULL }, 00228 { "member", GDB_XML_AF_OPTIONAL, NULL, NULL }, 00229 { "text_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 00230 { "text_size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 00231 { "data_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 00232 { "data_size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 00233 { NULL, GDB_XML_AF_NONE, NULL, NULL } 00234 }; 00235 00236 static const struct gdb_xml_element library_list_children[] = 00237 { 00238 { "library", library_attributes, NULL, 00239 GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL, 00240 library_list_start_library, NULL}, 00241 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 00242 }; 00243 00244 static const struct gdb_xml_attribute library_list_attributes[] = 00245 { 00246 { "version", GDB_XML_AF_NONE, NULL, NULL }, 00247 { NULL, GDB_XML_AF_NONE, NULL, NULL } 00248 }; 00249 00250 static const struct gdb_xml_element library_list_elements[] = 00251 { 00252 { "library-list-aix", library_list_attributes, library_list_children, 00253 GDB_XML_EF_NONE, library_list_start_list, NULL }, 00254 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 00255 }; 00256 00257 /* Parse LIBRARY, a string containing the loader info in XML format, 00258 and return an lm_info_p vector. 00259 00260 Return NULL if the parsing failed. */ 00261 00262 static VEC (lm_info_p) * 00263 solib_aix_parse_libraries (const char *library) 00264 { 00265 VEC (lm_info_p) *result = NULL; 00266 struct cleanup *back_to = make_cleanup (solib_aix_free_library_list, 00267 &result); 00268 00269 if (gdb_xml_parse_quick (_("aix library list"), "library-list-aix.dtd", 00270 library_list_elements, library, &result) == 0) 00271 { 00272 /* Parsed successfully, keep the result. */ 00273 discard_cleanups (back_to); 00274 return result; 00275 } 00276 00277 do_cleanups (back_to); 00278 return NULL; 00279 } 00280 00281 #endif /* HAVE_LIBEXPAT */ 00282 00283 /* Return the loader info for the given inferior (INF), or NULL if 00284 the list could not be computed. 00285 00286 Cache the result in per-inferior data, so as to avoid recomputing it 00287 each time this function is called. 00288 00289 If an error occurs while computing this list, and WARNING_MSG 00290 is not NULL, then print a warning including WARNING_MSG and 00291 a description of the error. */ 00292 00293 static VEC (lm_info_p) * 00294 solib_aix_get_library_list (struct inferior *inf, const char *warning_msg) 00295 { 00296 struct solib_aix_inferior_data *data; 00297 char *library_document; 00298 struct cleanup *cleanup; 00299 00300 /* If already computed, return the cached value. */ 00301 data = get_solib_aix_inferior_data (inf); 00302 if (data->library_list != NULL) 00303 return data->library_list; 00304 00305 library_document = target_read_stralloc (¤t_target, 00306 TARGET_OBJECT_LIBRARIES_AIX, 00307 NULL); 00308 if (library_document == NULL && warning_msg != NULL) 00309 { 00310 warning (_("%s (failed to read TARGET_OBJECT_LIBRARIES_AIX)"), 00311 warning_msg); 00312 return NULL; 00313 } 00314 cleanup = make_cleanup (xfree, library_document); 00315 00316 if (solib_aix_debug) 00317 fprintf_unfiltered (gdb_stdlog, 00318 "DEBUG: TARGET_OBJECT_LIBRARIES_AIX = \n%s\n", 00319 library_document); 00320 00321 data->library_list = solib_aix_parse_libraries (library_document); 00322 if (data->library_list == NULL && warning_msg != NULL) 00323 { 00324 warning (_("%s (missing XML support?)"), warning_msg); 00325 do_cleanups (cleanup); 00326 return NULL; 00327 } 00328 00329 do_cleanups (cleanup); 00330 return data->library_list; 00331 } 00332 00333 /* If the .bss section's VMA is set to an address located before 00334 the end of the .data section, causing the two sections to overlap, 00335 return the overlap in bytes. Otherwise, return zero. 00336 00337 Motivation: 00338 00339 The GNU linker sometimes sets the start address of the .bss session 00340 before the end of the .data section, making the 2 sections overlap. 00341 The loader appears to handle this situation gracefully, by simply 00342 loading the bss section right after the end of the .data section. 00343 00344 This means that the .data and the .bss sections are sometimes 00345 no longer relocated by the same amount. The problem is that 00346 the ldinfo data does not contain any information regarding 00347 the relocation of the .bss section, assuming that it would be 00348 identical to the information provided for the .data section 00349 (this is what would normally happen if the program was linked 00350 correctly). 00351 00352 GDB therefore needs to detect those cases, and make the corresponding 00353 adjustment to the .bss section offset computed from the ldinfo data 00354 when necessary. This function returns the adjustment amount (or 00355 zero when no adjustment is needed). */ 00356 00357 static CORE_ADDR 00358 solib_aix_bss_data_overlap (bfd *abfd) 00359 { 00360 struct bfd_section *data_sect, *bss_sect; 00361 00362 data_sect = bfd_get_section_by_name (abfd, ".data"); 00363 if (data_sect == NULL) 00364 return 0; /* No overlap possible. */ 00365 00366 bss_sect = bfd_get_section_by_name (abfd, ".bss"); 00367 if (bss_sect == NULL) 00368 return 0; /* No overlap possible. */ 00369 00370 /* Assume the problem only occurs with linkers that place the .bss 00371 section after the .data section (the problem has only been 00372 observed when using the GNU linker, and the default linker 00373 script always places the .data and .bss sections in that order). */ 00374 if (bfd_section_vma (abfd, bss_sect) 00375 < bfd_section_vma (abfd, data_sect)) 00376 return 0; 00377 00378 if (bfd_section_vma (abfd, bss_sect) 00379 < bfd_section_vma (abfd, data_sect) + bfd_get_section_size (data_sect)) 00380 return ((bfd_section_vma (abfd, data_sect) 00381 + bfd_get_section_size (data_sect)) 00382 - bfd_section_vma (abfd, bss_sect)); 00383 00384 return 0; 00385 } 00386 00387 /* Implement the "relocate_section_addresses" target_so_ops method. */ 00388 00389 static void 00390 solib_aix_relocate_section_addresses (struct so_list *so, 00391 struct target_section *sec) 00392 { 00393 struct bfd_section *bfd_sect = sec->the_bfd_section; 00394 bfd *abfd = bfd_sect->owner; 00395 const char *section_name = bfd_section_name (abfd, bfd_sect); 00396 struct lm_info *info = so->lm_info; 00397 00398 if (strcmp (section_name, ".text") == 0) 00399 { 00400 sec->addr = info->text_addr; 00401 sec->endaddr = sec->addr + info->text_size; 00402 00403 /* The text address given to us by the loader contains 00404 XCOFF headers, so we need to adjust by this much. */ 00405 sec->addr += bfd_sect->filepos; 00406 } 00407 else if (strcmp (section_name, ".data") == 0) 00408 { 00409 sec->addr = info->data_addr; 00410 sec->endaddr = sec->addr + info->data_size; 00411 } 00412 else if (strcmp (section_name, ".bss") == 0) 00413 { 00414 /* The information provided by the loader does not include 00415 the address of the .bss section, but we know that it gets 00416 relocated by the same offset as the .data section. So, 00417 compute the relocation offset for the .data section, and 00418 apply it to the .bss section as well. If the .data section 00419 is not defined (which seems highly unlikely), do our best 00420 by assuming no relocation. */ 00421 struct bfd_section *data_sect 00422 = bfd_get_section_by_name (abfd, ".data"); 00423 CORE_ADDR data_offset = 0; 00424 00425 if (data_sect != NULL) 00426 data_offset = info->data_addr - bfd_section_vma (abfd, data_sect); 00427 00428 sec->addr = bfd_section_vma (abfd, bfd_sect) + data_offset; 00429 sec->addr += solib_aix_bss_data_overlap (abfd); 00430 sec->endaddr = sec->addr + bfd_section_size (abfd, bfd_sect); 00431 } 00432 else 00433 { 00434 /* All other sections should not be relocated. */ 00435 sec->addr = bfd_section_vma (abfd, bfd_sect); 00436 sec->endaddr = sec->addr + bfd_section_size (abfd, bfd_sect); 00437 } 00438 } 00439 00440 /* Implement the "free_so" target_so_ops method. */ 00441 00442 static void 00443 solib_aix_free_so (struct so_list *so) 00444 { 00445 if (solib_aix_debug) 00446 fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_so (%s)\n", 00447 so->so_name); 00448 solib_aix_xfree_lm_info (so->lm_info); 00449 } 00450 00451 /* Implement the "clear_solib" target_so_ops method. */ 00452 00453 static void 00454 solib_aix_clear_solib (void) 00455 { 00456 /* Nothing needed. */ 00457 } 00458 00459 /* Compute and return the OBJFILE's section_offset array, using 00460 the associated loader info (INFO). 00461 00462 The resulting array is computed on the heap and must be 00463 deallocated after use. */ 00464 00465 static struct section_offsets * 00466 solib_aix_get_section_offsets (struct objfile *objfile, 00467 struct lm_info *info) 00468 { 00469 struct section_offsets *offsets; 00470 bfd *abfd = objfile->obfd; 00471 int i; 00472 00473 offsets = XCALLOC (objfile->num_sections, struct section_offsets); 00474 00475 /* .text */ 00476 00477 if (objfile->sect_index_text != -1) 00478 { 00479 struct bfd_section *sect 00480 = objfile->sections[objfile->sect_index_text].the_bfd_section; 00481 00482 offsets->offsets[objfile->sect_index_text] 00483 = info->text_addr + sect->filepos - bfd_section_vma (abfd, sect); 00484 } 00485 00486 /* .data */ 00487 00488 if (objfile->sect_index_data != -1) 00489 { 00490 struct bfd_section *sect 00491 = objfile->sections[objfile->sect_index_data].the_bfd_section; 00492 00493 offsets->offsets[objfile->sect_index_data] 00494 = info->data_addr - bfd_section_vma (abfd, sect); 00495 } 00496 00497 /* .bss 00498 00499 The offset of the .bss section should be identical to the offset 00500 of the .data section. If no .data section (which seems hard to 00501 believe it is possible), assume it is zero. */ 00502 00503 if (objfile->sect_index_bss != -1 00504 && objfile->sect_index_data != -1) 00505 { 00506 offsets->offsets[objfile->sect_index_bss] 00507 = (offsets->offsets[objfile->sect_index_data] 00508 + solib_aix_bss_data_overlap (abfd)); 00509 } 00510 00511 /* All other sections should not need relocation. */ 00512 00513 return offsets; 00514 } 00515 00516 /* Implement the "solib_create_inferior_hook" target_so_ops method. */ 00517 00518 static void 00519 solib_aix_solib_create_inferior_hook (int from_tty) 00520 { 00521 const char *warning_msg = "unable to relocate main executable"; 00522 VEC (lm_info_p) *library_list; 00523 struct lm_info *exec_info; 00524 00525 /* We need to relocate the main executable... */ 00526 00527 library_list = solib_aix_get_library_list (current_inferior (), 00528 warning_msg); 00529 if (library_list == NULL) 00530 return; /* Warning already printed. */ 00531 00532 if (VEC_length (lm_info_p, library_list) < 1) 00533 { 00534 warning (_("unable to relocate main executable (no info from loader)")); 00535 return; 00536 } 00537 00538 exec_info = VEC_index (lm_info_p, library_list, 0); 00539 00540 if (symfile_objfile != NULL) 00541 { 00542 struct section_offsets *offsets 00543 = solib_aix_get_section_offsets (symfile_objfile, exec_info); 00544 struct cleanup *cleanup = make_cleanup (xfree, offsets); 00545 00546 objfile_relocate (symfile_objfile, offsets); 00547 do_cleanups (cleanup); 00548 } 00549 } 00550 00551 /* Implement the "special_symbol_handling" target_so_ops method. */ 00552 00553 static void 00554 solib_aix_special_symbol_handling (void) 00555 { 00556 /* Nothing needed. */ 00557 } 00558 00559 /* Implement the "current_sos" target_so_ops method. */ 00560 00561 static struct so_list * 00562 solib_aix_current_sos (void) 00563 { 00564 struct so_list *start = NULL, *last = NULL; 00565 VEC (lm_info_p) *library_list; 00566 struct lm_info *info; 00567 int ix; 00568 00569 library_list = solib_aix_get_library_list (current_inferior (), NULL); 00570 if (library_list == NULL) 00571 return NULL; 00572 00573 /* Build a struct so_list for each entry on the list. 00574 We skip the first entry, since this is the entry corresponding 00575 to the main executable, not a shared library. */ 00576 for (ix = 1; VEC_iterate (lm_info_p, library_list, ix, info); ix++) 00577 { 00578 struct so_list *new_solib = XZALLOC (struct so_list); 00579 char *so_name; 00580 00581 if (info->member_name == NULL) 00582 { 00583 /* INFO->FILENAME is probably not an archive, but rather 00584 a shared object. Unusual, but it should be possible 00585 to link a program against a shared object directory, 00586 without having to put it in an archive first. */ 00587 so_name = xstrdup (info->filename); 00588 } 00589 else 00590 { 00591 /* This is the usual case on AIX, where the shared object 00592 is a member of an archive. Create a synthetic so_name 00593 that follows the same convention as AIX's ldd tool 00594 (Eg: "/lib/libc.a(shr.o)"). */ 00595 so_name = xstrprintf ("%s(%s)", info->filename, info->member_name); 00596 } 00597 strncpy (new_solib->so_original_name, so_name, 00598 SO_NAME_MAX_PATH_SIZE - 1); 00599 new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; 00600 memcpy (new_solib->so_name, new_solib->so_original_name, 00601 SO_NAME_MAX_PATH_SIZE); 00602 new_solib->lm_info = solib_aix_new_lm_info (info); 00603 00604 /* Add it to the list. */ 00605 if (!start) 00606 last = start = new_solib; 00607 else 00608 { 00609 last->next = new_solib; 00610 last = new_solib; 00611 } 00612 } 00613 00614 return start; 00615 } 00616 00617 /* Implement the "open_symbol_file_object" target_so_ops method. */ 00618 00619 static int 00620 solib_aix_open_symbol_file_object (void *from_ttyp) 00621 { 00622 return 0; 00623 } 00624 00625 /* Implement the "in_dynsym_resolve_code" target_so_ops method. */ 00626 00627 static int 00628 solib_aix_in_dynsym_resolve_code (CORE_ADDR pc) 00629 { 00630 return 0; 00631 } 00632 00633 /* Implement the "bfd_open" target_so_ops method. */ 00634 00635 static bfd * 00636 solib_aix_bfd_open (char *pathname) 00637 { 00638 /* The pathname is actually a synthetic filename with the following 00639 form: "/path/to/sharedlib(member.o)" (double-quotes excluded). 00640 split this into archive name and member name. 00641 00642 FIXME: This is a little hacky. Perhaps we should provide access 00643 to the solib's lm_info here? */ 00644 const int path_len = strlen (pathname); 00645 char *sep; 00646 char *filename; 00647 int filename_len; 00648 char *member_name; 00649 bfd *archive_bfd, *object_bfd; 00650 struct cleanup *cleanup; 00651 00652 if (pathname[path_len - 1] != ')') 00653 return solib_bfd_open (pathname); 00654 00655 /* Search for the associated parens. */ 00656 sep = strrchr (pathname, '('); 00657 if (sep == NULL) 00658 { 00659 /* Should never happen, but recover as best as we can (trying 00660 to open pathname without decoding, possibly leading to 00661 a failure), rather than triggering an assert failure). */ 00662 warning (_("missing '(' in shared object pathname: %s"), pathname); 00663 return solib_bfd_open (pathname); 00664 } 00665 filename_len = sep - pathname; 00666 00667 filename = xstrprintf ("%.*s", filename_len, pathname); 00668 cleanup = make_cleanup (xfree, filename); 00669 member_name = xstrprintf ("%.*s", path_len - filename_len - 2, sep + 1); 00670 make_cleanup (xfree, member_name); 00671 00672 archive_bfd = gdb_bfd_open (filename, gnutarget, -1); 00673 if (archive_bfd == NULL) 00674 { 00675 warning (_("Could not open `%s' as an executable file: %s"), 00676 filename, bfd_errmsg (bfd_get_error ())); 00677 do_cleanups (cleanup); 00678 return NULL; 00679 } 00680 00681 if (bfd_check_format (archive_bfd, bfd_object)) 00682 { 00683 do_cleanups (cleanup); 00684 return archive_bfd; 00685 } 00686 00687 if (! bfd_check_format (archive_bfd, bfd_archive)) 00688 { 00689 warning (_("\"%s\": not in executable format: %s."), 00690 filename, bfd_errmsg (bfd_get_error ())); 00691 gdb_bfd_unref (archive_bfd); 00692 do_cleanups (cleanup); 00693 return NULL; 00694 } 00695 00696 object_bfd = gdb_bfd_openr_next_archived_file (archive_bfd, NULL); 00697 while (object_bfd != NULL) 00698 { 00699 bfd *next; 00700 00701 if (strcmp (member_name, object_bfd->filename) == 0) 00702 break; 00703 00704 next = gdb_bfd_openr_next_archived_file (archive_bfd, object_bfd); 00705 gdb_bfd_unref (object_bfd); 00706 object_bfd = next; 00707 } 00708 00709 if (object_bfd == NULL) 00710 { 00711 warning (_("\"%s\": member \"%s\" missing."), filename, member_name); 00712 gdb_bfd_unref (archive_bfd); 00713 do_cleanups (cleanup); 00714 return NULL; 00715 } 00716 00717 if (! bfd_check_format (object_bfd, bfd_object)) 00718 { 00719 warning (_("%s(%s): not in object format: %s."), 00720 filename, member_name, bfd_errmsg (bfd_get_error ())); 00721 gdb_bfd_unref (archive_bfd); 00722 gdb_bfd_unref (object_bfd); 00723 do_cleanups (cleanup); 00724 return NULL; 00725 } 00726 00727 gdb_bfd_unref (archive_bfd); 00728 do_cleanups (cleanup); 00729 return object_bfd; 00730 } 00731 00732 /* Return the obj_section corresponding to OBJFILE's data section, 00733 or NULL if not found. */ 00734 /* FIXME: Define in a more general location? */ 00735 00736 static struct obj_section * 00737 data_obj_section_from_objfile (struct objfile *objfile) 00738 { 00739 struct obj_section *osect; 00740 00741 ALL_OBJFILE_OSECTIONS (objfile, osect) 00742 if (strcmp (bfd_section_name (objfile->obfd, osect->the_bfd_section), 00743 ".data") == 0) 00744 return osect; 00745 00746 return NULL; 00747 } 00748 00749 /* Return the TOC value corresponding to the given PC address, 00750 or raise an error if the value could not be determined. */ 00751 00752 CORE_ADDR 00753 solib_aix_get_toc_value (CORE_ADDR pc) 00754 { 00755 struct obj_section *pc_osect = find_pc_section (pc); 00756 struct obj_section *data_osect; 00757 CORE_ADDR result; 00758 00759 if (pc_osect == NULL) 00760 error (_("unable to find TOC entry for pc %s " 00761 "(no section contains this PC)"), 00762 core_addr_to_string (pc)); 00763 00764 data_osect = data_obj_section_from_objfile (pc_osect->objfile); 00765 if (data_osect == NULL) 00766 error (_("unable to find TOC entry for pc %s " 00767 "(%s has no data section)"), 00768 core_addr_to_string (pc), objfile_name (pc_osect->objfile)); 00769 00770 result = (obj_section_addr (data_osect) 00771 + xcoff_get_toc_offset (pc_osect->objfile)); 00772 if (solib_aix_debug) 00773 fprintf_unfiltered (gdb_stdlog, 00774 "DEBUG: solib_aix_get_toc_value (pc=%s) -> %s\n", 00775 core_addr_to_string (pc), 00776 core_addr_to_string (result)); 00777 00778 return result; 00779 } 00780 00781 /* This module's normal_stop observer. */ 00782 00783 static void 00784 solib_aix_normal_stop_observer (struct bpstats *unused_1, int unused_2) 00785 { 00786 struct solib_aix_inferior_data *data 00787 = get_solib_aix_inferior_data (current_inferior ()); 00788 00789 /* The inferior execution has been resumed, and it just stopped 00790 again. This means that the list of shared libraries may have 00791 evolved. Reset our cached value. */ 00792 solib_aix_free_library_list (&data->library_list); 00793 } 00794 00795 /* Implements the "show debug aix-solib" command. */ 00796 00797 static void 00798 show_solib_aix_debug (struct ui_file *file, int from_tty, 00799 struct cmd_list_element *c, const char *value) 00800 { 00801 fprintf_filtered (file, _("solib-aix debugging is %s.\n"), value); 00802 } 00803 00804 /* The target_so_ops for AIX targets. */ 00805 struct target_so_ops solib_aix_so_ops; 00806 00807 /* -Wmissing-prototypes */ 00808 extern initialize_file_ftype _initialize_solib_aix; 00809 00810 void 00811 _initialize_solib_aix (void) 00812 { 00813 solib_aix_so_ops.relocate_section_addresses 00814 = solib_aix_relocate_section_addresses; 00815 solib_aix_so_ops.free_so = solib_aix_free_so; 00816 solib_aix_so_ops.clear_solib = solib_aix_clear_solib; 00817 solib_aix_so_ops.solib_create_inferior_hook 00818 = solib_aix_solib_create_inferior_hook; 00819 solib_aix_so_ops.special_symbol_handling 00820 = solib_aix_special_symbol_handling; 00821 solib_aix_so_ops.current_sos = solib_aix_current_sos; 00822 solib_aix_so_ops.open_symbol_file_object 00823 = solib_aix_open_symbol_file_object; 00824 solib_aix_so_ops.in_dynsym_resolve_code 00825 = solib_aix_in_dynsym_resolve_code; 00826 solib_aix_so_ops.bfd_open = solib_aix_bfd_open; 00827 00828 solib_aix_inferior_data_handle = register_inferior_data (); 00829 00830 observer_attach_normal_stop (solib_aix_normal_stop_observer); 00831 00832 /* Debug this file's internals. */ 00833 add_setshow_boolean_cmd ("aix-solib", class_maintenance, 00834 &solib_aix_debug, _("\ 00835 Control the debugging traces for the solib-aix module."), _("\ 00836 Show whether solib-aix debugging traces are enabled."), _("\ 00837 When on, solib-aix debugging traces are enabled."), 00838 NULL, 00839 show_solib_aix_debug, 00840 &setdebuglist, &showdebuglist); 00841 }