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