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