1 /* Copyright (C) 2013 Free Software Foundation, Inc.
3 This file is part of GDB.
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.
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.
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/>. */
19 #include "solib-aix.h"
26 #include "xcoffread.h"
30 /* Variable controlling the output of the debugging traces for
32 static int solib_aix_debug;
34 /* Our private data in struct so_list. */
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"
44 /* The name of the shared object file with the actual dynamic
45 loading dependency. This may be NULL (Eg. main executable). */
48 /* The address in inferior memory where the text section got mapped. */
51 /* The size of the text section, obtained via the loader data. */
54 /* The address in inferior memory where the data section got mapped. */
57 /* The size of the data section, obtained via the loader data. */
61 typedef struct lm_info *lm_info_p;
64 /* Return a deep copy of the given struct lm_info object. */
66 static struct lm_info *
67 solib_aix_new_lm_info (struct lm_info *info)
69 struct lm_info *result = xmalloc (sizeof (struct lm_info));
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);
79 /* Free the memory allocated for the given lm_info. */
82 solib_aix_xfree_lm_info (struct lm_info *info)
84 xfree (info->filename);
85 xfree (info->member_name);
89 /* This module's per-inferior data. */
91 struct solib_aix_inferior_data
93 /* The list of shared libraries. NULL if not computed yet.
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
101 VEC (lm_info_p) *library_list;
104 /* Key to our per-inferior data. */
105 static const struct inferior_data *solib_aix_inferior_data_handle;
107 /* Return this module's data for the given inferior.
108 If none is found, add a zero'ed one now. */
110 static struct solib_aix_inferior_data *
111 get_solib_aix_inferior_data (struct inferior *inf)
113 struct solib_aix_inferior_data *data;
115 data = inferior_data (inf, solib_aix_inferior_data_handle);
118 data = XZALLOC (struct solib_aix_inferior_data);
119 set_inferior_data (inf, solib_aix_inferior_data_handle, data);
125 #if !defined(HAVE_LIBEXPAT)
127 /* Dummy implementation if XML support is not compiled in. */
129 static VEC (lm_info_p) *
130 solib_aix_parse_libraries (const char *library)
132 static int have_warned;
137 warning (_("Can not parse XML library list; XML support was disabled "
144 /* Dummy implementation if XML support is not compiled in. */
147 solib_aix_free_library_list (void *p)
151 #else /* HAVE_LIBEXPAT */
153 #include "xml-support.h"
155 /* Handle the start of a <library> element. */
158 library_list_start_library (struct gdb_xml_parser *parser,
159 const struct gdb_xml_element *element,
161 VEC (gdb_xml_value_s) *attributes)
163 VEC (lm_info_p) **list = user_data;
164 struct lm_info *item = XZALLOC (struct lm_info);
165 struct gdb_xml_value *attr;
167 attr = xml_find_attribute (attributes, "name");
168 item->filename = xstrdup (attr->value);
170 attr = xml_find_attribute (attributes, "member");
172 item->member_name = xstrdup (attr->value);
174 attr = xml_find_attribute (attributes, "text_addr");
175 item->text_addr = * (ULONGEST *) attr->value;
177 attr = xml_find_attribute (attributes, "text_size");
178 item->text_size = * (ULONGEST *) attr->value;
180 attr = xml_find_attribute (attributes, "data_addr");
181 item->data_addr = * (ULONGEST *) attr->value;
183 attr = xml_find_attribute (attributes, "data_size");
184 item->data_size = * (ULONGEST *) attr->value;
186 VEC_safe_push (lm_info_p, *list, item);
189 /* Handle the start of a <library-list-aix> element. */
192 library_list_start_list (struct gdb_xml_parser *parser,
193 const struct gdb_xml_element *element,
194 void *user_data, VEC (gdb_xml_value_s) *attributes)
196 char *version = xml_find_attribute (attributes, "version")->value;
198 if (strcmp (version, "1.0") != 0)
199 gdb_xml_error (parser,
200 _("Library list has unsupported version \"%s\""),
204 /* Discard the constructed library list. */
207 solib_aix_free_library_list (void *p)
209 VEC (lm_info_p) **result = p;
210 struct lm_info *info;
214 fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_library_list\n");
216 for (ix = 0; VEC_iterate (lm_info_p, *result, ix, info); ix++)
217 solib_aix_xfree_lm_info (info);
218 VEC_free (lm_info_p, *result);
222 /* The allowed elements and attributes for an AIX library list
223 described in XML format. The root element is a <library-list-aix>. */
225 static const struct gdb_xml_attribute library_attributes[] =
227 { "name", GDB_XML_AF_NONE, NULL, NULL },
228 { "member", GDB_XML_AF_OPTIONAL, NULL, NULL },
229 { "text_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
230 { "text_size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
231 { "data_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
232 { "data_size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
233 { NULL, GDB_XML_AF_NONE, NULL, NULL }
236 static const struct gdb_xml_element library_list_children[] =
238 { "library", library_attributes, NULL,
239 GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
240 library_list_start_library, NULL},
241 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
244 static const struct gdb_xml_attribute library_list_attributes[] =
246 { "version", GDB_XML_AF_NONE, NULL, NULL },
247 { NULL, GDB_XML_AF_NONE, NULL, NULL }
250 static const struct gdb_xml_element library_list_elements[] =
252 { "library-list-aix", library_list_attributes, library_list_children,
253 GDB_XML_EF_NONE, library_list_start_list, NULL },
254 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
257 /* Parse LIBRARY, a string containing the loader info in XML format,
258 and return an lm_info_p vector.
260 Return NULL if the parsing failed. */
262 static VEC (lm_info_p) *
263 solib_aix_parse_libraries (const char *library)
265 VEC (lm_info_p) *result = NULL;
266 struct cleanup *back_to = make_cleanup (solib_aix_free_library_list,
269 if (gdb_xml_parse_quick (_("aix library list"), "library-list-aix.dtd",
270 library_list_elements, library, &result) == 0)
272 /* Parsed successfully, keep the result. */
273 discard_cleanups (back_to);
277 do_cleanups (back_to);
281 #endif /* HAVE_LIBEXPAT */
283 /* Return the loader info for the given inferior (INF), or NULL if
284 the list could not be computed.
286 Cache the result in per-inferior data, so as to avoid recomputing it
287 each time this function is called.
289 If an error occurs while computing this list, and WARNING_MSG
290 is not NULL, then print a warning including WARNING_MSG and
291 a description of the error. */
293 static VEC (lm_info_p) *
294 solib_aix_get_library_list (struct inferior *inf, const char *warning_msg)
296 struct solib_aix_inferior_data *data;
297 char *library_document;
298 struct cleanup *cleanup;
300 /* If already computed, return the cached value. */
301 data = get_solib_aix_inferior_data (inf);
302 if (data->library_list != NULL)
303 return data->library_list;
305 library_document = target_read_stralloc (¤t_target,
306 TARGET_OBJECT_LIBRARIES_AIX,
308 if (library_document == NULL && warning_msg != NULL)
310 warning (_("%s (failed to read TARGET_OBJECT_LIBRARIES_AIX)"),
314 cleanup = make_cleanup (xfree, library_document);
317 fprintf_unfiltered (gdb_stdlog,
318 "DEBUG: TARGET_OBJECT_LIBRARIES_AIX = \n%s\n",
321 data->library_list = solib_aix_parse_libraries (library_document);
322 if (data->library_list == NULL && warning_msg != NULL)
324 warning (_("%s (missing XML support?)"), warning_msg);
325 do_cleanups (cleanup);
329 do_cleanups (cleanup);
330 return data->library_list;
333 /* If the .bss section's VMA is set to an address located before
334 the end of the .data section, causing the two sections to overlap,
335 return the overlap in bytes. Otherwise, return zero.
339 The GNU linker sometimes sets the start address of the .bss session
340 before the end of the .data section, making the 2 sections overlap.
341 The loader appears to handle this situation gracefully, by simply
342 loading the bss section right after the end of the .data section.
344 This means that the .data and the .bss sections are sometimes
345 no longer relocated by the same amount. The problem is that
346 the ldinfo data does not contain any information regarding
347 the relocation of the .bss section, assuming that it would be
348 identical to the information provided for the .data section
349 (this is what would normally happen if the program was linked
352 GDB therefore needs to detect those cases, and make the corresponding
353 adjustment to the .bss section offset computed from the ldinfo data
354 when necessary. This function returns the adjustment amount (or
355 zero when no adjustment is needed). */
358 solib_aix_bss_data_overlap (bfd *abfd)
360 struct bfd_section *data_sect, *bss_sect;
362 data_sect = bfd_get_section_by_name (abfd, ".data");
363 if (data_sect == NULL)
364 return 0; /* No overlap possible. */
366 bss_sect = bfd_get_section_by_name (abfd, ".bss");
367 if (bss_sect == NULL)
368 return 0; /* No overlap possible. */
370 /* Assume the problem only occurs with linkers that place the .bss
371 section after the .data section (the problem has only been
372 observed when using the GNU linker, and the default linker
373 script always places the .data and .bss sections in that order). */
374 if (bfd_section_vma (abfd, bss_sect)
375 < bfd_section_vma (abfd, data_sect))
378 if (bfd_section_vma (abfd, bss_sect)
379 < bfd_section_vma (abfd, data_sect) + bfd_get_section_size (data_sect))
380 return ((bfd_section_vma (abfd, data_sect)
381 + bfd_get_section_size (data_sect))
382 - bfd_section_vma (abfd, bss_sect));
387 /* Implement the "relocate_section_addresses" target_so_ops method. */
390 solib_aix_relocate_section_addresses (struct so_list *so,
391 struct target_section *sec)
393 bfd *abfd = sec->bfd;
394 struct bfd_section *bfd_sect = sec->the_bfd_section;
395 const char *section_name = bfd_section_name (abfd, bfd_sect);
396 struct lm_info *info = so->lm_info;
398 if (strcmp (section_name, ".text") == 0)
400 sec->addr = info->text_addr;
401 sec->endaddr = sec->addr + info->text_size;
403 /* The text address given to us by the loader contains
404 XCOFF headers, so we need to adjust by this much. */
405 sec->addr += bfd_sect->filepos;
407 else if (strcmp (section_name, ".data") == 0)
409 sec->addr = info->data_addr;
410 sec->endaddr = sec->addr + info->data_size;
412 else if (strcmp (section_name, ".bss") == 0)
414 /* The information provided by the loader does not include
415 the address of the .bss section, but we know that it gets
416 relocated by the same offset as the .data section. So,
417 compute the relocation offset for the .data section, and
418 apply it to the .bss section as well. If the .data section
419 is not defined (which seems highly unlikely), do our best
420 by assuming no relocation. */
421 struct bfd_section *data_sect
422 = bfd_get_section_by_name (abfd, ".data");
423 CORE_ADDR data_offset = 0;
425 if (data_sect != NULL)
426 data_offset = info->data_addr - bfd_section_vma (abfd, data_sect);
428 sec->addr = bfd_section_vma (abfd, bfd_sect) + data_offset;
429 sec->addr += solib_aix_bss_data_overlap (abfd);
430 sec->endaddr = sec->addr + bfd_section_size (abfd, bfd_sect);
434 /* All other sections should not be relocated. */
435 /* FIXME: GDB complains that the .loader section sometimes
436 overlaps with other sections (Eg: the .data section).
437 As far as I can tell, the loader section had the LOAD flag
438 set, but not the RELOC. So it should not be relocated.
439 There seems to be a problem there, and maybe it has to do
440 with setting sec->addr to 0 (when the vma is indeed 0).
441 But even if there wasn't, the problem then becomes the fact
442 that many shared objects inside shared libraries have
443 a .loader section whose vma is 0, thus also triggering
444 an overlap warning. */
445 sec->addr = bfd_section_vma (abfd, bfd_sect);
446 sec->endaddr = sec->addr + bfd_section_size (abfd, bfd_sect);
450 /* Implement the "free_so" target_so_ops method. */
453 solib_aix_free_so (struct so_list *so)
456 fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_so (%s)\n",
458 solib_aix_xfree_lm_info (so->lm_info);
461 /* Implement the "clear_solib" target_so_ops method. */
464 solib_aix_clear_solib (void)
466 /* Nothing needed. */
469 /* Compute and return the OBJFILE's section_offset array, using
470 the associated loader info (INFO).
472 The resulting array is computed on the heap and must be
473 deallocated after use. */
475 static struct section_offsets *
476 solib_aix_get_section_offsets (struct objfile *objfile,
477 struct lm_info *info)
479 struct section_offsets *offsets;
480 bfd *abfd = objfile->obfd;
483 offsets = XCALLOC (objfile->num_sections, struct section_offsets);
487 if (objfile->sect_index_text != -1)
489 struct bfd_section *sect
490 = objfile->sections[objfile->sect_index_text].the_bfd_section;
492 offsets->offsets[objfile->sect_index_text]
493 = info->text_addr + sect->filepos - bfd_section_vma (abfd, sect);
498 if (objfile->sect_index_data != -1)
500 struct bfd_section *sect
501 = objfile->sections[objfile->sect_index_data].the_bfd_section;
503 offsets->offsets[objfile->sect_index_data]
504 = info->data_addr - bfd_section_vma (abfd, sect);
509 The offset of the .bss section should be identical to the offset
510 of the .data section. If no .data section (which seems hard to
511 believe it is possible), assume it is zero. */
513 if (objfile->sect_index_bss != -1
514 && objfile->sect_index_data != -1)
516 offsets->offsets[objfile->sect_index_bss]
517 = (offsets->offsets[objfile->sect_index_data]
518 + solib_aix_bss_data_overlap (abfd));
521 /* All other sections should not need relocation. */
526 /* Implement the "solib_create_inferior_hook" target_so_ops method. */
529 solib_aix_solib_create_inferior_hook (int from_tty)
531 const char *warning_msg = "unable to relocate main executable";
532 VEC (lm_info_p) *library_list;
533 struct lm_info *exec_info;
535 /* We need to relocate the main executable... */
537 library_list = solib_aix_get_library_list (current_inferior (),
539 if (library_list == NULL)
540 return; /* Warning already printed. */
542 if (VEC_length (lm_info_p, library_list) < 1)
544 warning (_("unable to relocate main executable (no info from loader)"));
548 exec_info = VEC_index (lm_info_p, library_list, 0);
550 if (symfile_objfile != NULL)
552 struct section_offsets *offsets
553 = solib_aix_get_section_offsets (symfile_objfile, exec_info);
554 struct cleanup *cleanup = make_cleanup (xfree, offsets);
556 objfile_relocate (symfile_objfile, offsets);
557 do_cleanups (cleanup);
561 /* Implement the "special_symbol_handling" target_so_ops method. */
564 solib_aix_special_symbol_handling (void)
566 /* Nothing needed. */
569 /* Implement the "current_sos" target_so_ops method. */
571 static struct so_list *
572 solib_aix_current_sos (void)
574 struct so_list *start = NULL, *last = NULL;
575 VEC (lm_info_p) *library_list;
576 struct lm_info *info;
579 library_list = solib_aix_get_library_list (current_inferior (), NULL);
580 if (library_list == NULL)
583 /* Build a struct so_list for each entry on the list.
584 We skip the first entry, since this is the entry corresponding
585 to the main executable, not a shared library. */
586 for (ix = 1; VEC_iterate (lm_info_p, library_list, ix, info); ix++)
588 struct so_list *new_solib = XZALLOC (struct so_list);
591 if (info->member_name == NULL)
593 /* INFO->FILENAME is probably not an archive, but rather
594 a shared object. Unusual, but it should be possible
595 to link a program against a shared object directory,
596 without having to put it in an archive first. */
597 so_name = xstrdup (info->filename);
601 /* This is the usual case on AIX, where the shared object
602 is a member of an archive. Create a synthetic so_name
603 that follows the same convention as AIX's ldd tool
604 (Eg: "/lib/libc.a(shr.o)"). */
605 so_name = xstrprintf ("%s(%s)", info->filename, info->member_name);
607 strncpy (new_solib->so_original_name, so_name,
608 SO_NAME_MAX_PATH_SIZE - 1);
609 new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
610 memcpy (new_solib->so_name, new_solib->so_original_name,
611 SO_NAME_MAX_PATH_SIZE);
612 new_solib->lm_info = solib_aix_new_lm_info (info);
614 /* Add it to the list. */
616 last = start = new_solib;
619 last->next = new_solib;
627 /* Implement the "open_symbol_file_object" target_so_ops method. */
630 solib_aix_open_symbol_file_object (void *from_ttyp)
635 /* Implement the "in_dynsym_resolve_code" target_so_ops method. */
638 solib_aix_in_dynsym_resolve_code (CORE_ADDR pc)
643 /* Implement the "bfd_open" target_so_ops method. */
646 solib_aix_bfd_open (char *pathname)
648 /* The pathname is actually a synthetic filename with the following
649 form: "/path/to/sharedlib(member.o)" (double-quotes excluded).
650 split this into archive name and member name.
652 FIXME: This is a little hacky. Perhaps we should provide access
653 to the solib's lm_info here? */
654 const int path_len = strlen (pathname);
659 bfd *archive_bfd, *object_bfd;
660 struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
662 if (pathname[path_len - 1] != ')')
663 return solib_bfd_open (pathname);
665 /* Search for the associated parens. */
666 sep = strrchr (pathname, '(');
669 /* Should never happen, but recover as best as we can (trying
670 to open pathname without decoding, possibly leading to
671 a failure), rather than triggering an assert failure). */
672 warning (_("missing '(' in shared object pathname: %s"), pathname);
673 return solib_bfd_open (pathname);
675 filename_len = sep - pathname;
677 filename = xstrprintf ("%.*s", filename_len, pathname);
678 make_cleanup (xfree, filename);
679 member_name = xstrprintf ("%.*s", path_len - filename_len - 2, sep + 1);
680 make_cleanup (xfree, member_name);
682 archive_bfd = gdb_bfd_open (filename, gnutarget, -1);
683 if (archive_bfd == NULL)
685 warning (_("Could not open `%s' as an executable file: %s"),
686 filename, bfd_errmsg (bfd_get_error ()));
687 do_cleanups (cleanup);
691 if (bfd_check_format (archive_bfd, bfd_object))
693 do_cleanups (cleanup);
697 if (! bfd_check_format (archive_bfd, bfd_archive))
699 warning (_("\"%s\": not in executable format: %s."),
700 filename, bfd_errmsg (bfd_get_error ()));
701 gdb_bfd_unref (archive_bfd);
702 do_cleanups (cleanup);
706 object_bfd = gdb_bfd_openr_next_archived_file (archive_bfd, NULL);
707 while (object_bfd != NULL)
711 if (strcmp (member_name, object_bfd->filename) == 0)
714 next = gdb_bfd_openr_next_archived_file (archive_bfd, object_bfd);
715 gdb_bfd_unref (object_bfd);
719 if (object_bfd == NULL)
721 warning (_("\"%s\": member \"%s\" missing."), filename, member_name);
722 gdb_bfd_unref (archive_bfd);
723 do_cleanups (cleanup);
727 if (! bfd_check_format (object_bfd, bfd_object))
729 warning (_("%s(%s): not in object format: %s."),
730 filename, member_name, bfd_errmsg (bfd_get_error ()));
731 gdb_bfd_unref (archive_bfd);
732 gdb_bfd_unref (object_bfd);
733 do_cleanups (cleanup);
737 gdb_bfd_unref (archive_bfd);
738 do_cleanups (cleanup);
742 /* Return the obj_section corresponding to OBJFILE's data section,
743 or NULL if not found. */
744 /* FIXME: Define in a more general location? */
746 static struct obj_section *
747 data_obj_section_from_objfile (struct objfile *objfile)
749 struct obj_section *osect;
751 ALL_OBJFILE_OSECTIONS (objfile, osect)
752 if (strcmp (bfd_section_name (objfile->obfd, osect->the_bfd_section),
759 /* Return the TOC value corresponding to the given PC address,
760 or raise an error if the value could not be determined. */
763 solib_aix_get_toc_value (CORE_ADDR pc)
765 struct obj_section *pc_osect = find_pc_section (pc);
766 struct obj_section *data_osect;
769 if (pc_osect == NULL)
770 error (_("unable to find TOC entry for pc %s "
771 "(no section contains this PC)"),
772 core_addr_to_string (pc));
774 data_osect = data_obj_section_from_objfile (pc_osect->objfile);
775 if (data_osect == NULL)
776 error (_("unable to find TOC entry for pc %s "
777 "(%s has no data section)"),
778 core_addr_to_string (pc), pc_osect->objfile->name);
780 result = (obj_section_addr (data_osect)
781 + xcoff_get_toc_offset (pc_osect->objfile));
783 fprintf_unfiltered (gdb_stdlog,
784 "DEBUG: solib_aix_get_toc_value (pc=%s) -> %s\n",
785 core_addr_to_string (pc),
786 core_addr_to_string (result));
791 /* This module's normal_stop observer. */
794 solib_aix_normal_stop_observer (struct bpstats *unused_1, int unused_2)
796 struct solib_aix_inferior_data *data
797 = get_solib_aix_inferior_data (current_inferior ());
799 /* The inferior execution has been resumed, and it just stopped
800 again. This means that the list of shared libraries may have
801 evolved. Reset our cached value. */
802 solib_aix_free_library_list (&data->library_list);
805 /* Implements the "show debug aix-solib" command. */
808 show_solib_aix_debug (struct ui_file *file, int from_tty,
809 struct cmd_list_element *c, const char *value)
811 fprintf_filtered (file, _("solib-aix debugging is %s.\n"), value);
814 /* The target_so_ops for AIX targets. */
815 struct target_so_ops solib_aix_so_ops;
817 /* -Wmissing-prototypes */
818 extern initialize_file_ftype _initialize_solib_aix;
821 _initialize_solib_aix (void)
823 solib_aix_so_ops.relocate_section_addresses
824 = solib_aix_relocate_section_addresses;
825 solib_aix_so_ops.free_so = solib_aix_free_so;
826 solib_aix_so_ops.clear_solib = solib_aix_clear_solib;
827 solib_aix_so_ops.solib_create_inferior_hook
828 = solib_aix_solib_create_inferior_hook;
829 solib_aix_so_ops.special_symbol_handling
830 = solib_aix_special_symbol_handling;
831 solib_aix_so_ops.current_sos = solib_aix_current_sos;
832 solib_aix_so_ops.open_symbol_file_object
833 = solib_aix_open_symbol_file_object;
834 solib_aix_so_ops.in_dynsym_resolve_code
835 = solib_aix_in_dynsym_resolve_code;
836 solib_aix_so_ops.bfd_open = solib_aix_bfd_open;
838 solib_aix_inferior_data_handle = register_inferior_data ();
840 observer_attach_normal_stop (solib_aix_normal_stop_observer);
842 /* Debug this file's internals. */
843 add_setshow_boolean_cmd ("aix-solib", class_maintenance,
844 &solib_aix_debug, _("\
845 Control the debugging traces for the solib-aix module."), _("\
846 Show whether solib-aix debugging traces are enabled."), _("\
847 When on, solib-aix debugging traces are enabled."),
849 show_solib_aix_debug,
850 &setdebuglist, &showdebuglist);