Rename gdb/ChangeLog to gdb/ChangeLog-2021
[binutils-gdb.git] / gdb / solib-aix.c
blob772cf23d9a0951c64e6844e5d6ad5c70e46cf664
1 /* Copyright (C) 2013-2021 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/>. */
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"
31 /* Variable controlling the output of the debugging traces for
32 this module. */
33 static bool solib_aix_debug;
35 /* Print an "aix-solib" debug statement. */
37 #define solib_aix_debug_printf(fmt, ...) \
38 debug_prefixed_printf_cond (solib_aix_debug, "aix-solib",fmt, ##__VA_ARGS__)
40 /* Our private data in struct so_list. */
42 struct lm_info_aix : public lm_info_base
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;
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;
54 /* The address in inferior memory where the text section got mapped. */
55 CORE_ADDR text_addr = 0;
57 /* The size of the text section, obtained via the loader data. */
58 ULONGEST text_size = 0;
60 /* The address in inferior memory where the data section got mapped. */
61 CORE_ADDR data_addr = 0;
63 /* The size of the data section, obtained via the loader data. */
64 ULONGEST data_size = 0;
67 /* This module's per-inferior data. */
69 struct solib_aix_inferior_data
71 /* The list of shared libraries.
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;
82 /* Key to our per-inferior data. */
83 static inferior_key<solib_aix_inferior_data> solib_aix_inferior_data_handle;
85 /* Return this module's data for the given inferior.
86 If none is found, add a zero'ed one now. */
88 static struct solib_aix_inferior_data *
89 get_solib_aix_inferior_data (struct inferior *inf)
91 struct solib_aix_inferior_data *data;
93 data = solib_aix_inferior_data_handle.get (inf);
94 if (data == NULL)
95 data = solib_aix_inferior_data_handle.emplace (inf);
97 return data;
100 #if !defined(HAVE_LIBEXPAT)
102 /* Dummy implementation if XML support is not compiled in. */
104 static gdb::optional<std::vector<lm_info_aix>>
105 solib_aix_parse_libraries (const char *library)
107 static int have_warned;
109 if (!have_warned)
111 have_warned = 1;
112 warning (_("Can not parse XML library list; XML support was disabled "
113 "at compile time"));
116 return {};
119 #else /* HAVE_LIBEXPAT */
121 #include "xml-support.h"
123 /* Handle the start of a <library> element. */
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)
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;
135 attr = xml_find_attribute (attributes, "name");
136 item.filename = (const char *) attr->value.get ();
138 attr = xml_find_attribute (attributes, "member");
139 if (attr != NULL)
140 item.member_name = (const char *) attr->value.get ();
142 attr = xml_find_attribute (attributes, "text_addr");
143 item.text_addr = * (ULONGEST *) attr->value.get ();
145 attr = xml_find_attribute (attributes, "text_size");
146 item.text_size = * (ULONGEST *) attr->value.get ();
148 attr = xml_find_attribute (attributes, "data_addr");
149 item.data_addr = * (ULONGEST *) attr->value.get ();
151 attr = xml_find_attribute (attributes, "data_size");
152 item.data_size = * (ULONGEST *) attr->value.get ();
154 list->push_back (std::move (item));
157 /* Handle the start of a <library-list-aix> element. */
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)
165 char *version
166 = (char *) xml_find_attribute (attributes, "version")->value.get ();
168 if (strcmp (version, "1.0") != 0)
169 gdb_xml_error (parser,
170 _("Library list has unsupported version \"%s\""),
171 version);
174 /* The allowed elements and attributes for an AIX library list
175 described in XML format. The root element is a <library-list-aix>. */
177 static const struct gdb_xml_attribute library_attributes[] =
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 }
188 static const struct gdb_xml_element library_list_children[] =
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 }
196 static const struct gdb_xml_attribute library_list_attributes[] =
198 { "version", GDB_XML_AF_NONE, NULL, NULL },
199 { NULL, GDB_XML_AF_NONE, NULL, NULL }
202 static const struct gdb_xml_element library_list_elements[] =
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 }
209 /* Parse LIBRARY, a string containing the loader info in XML format,
210 and return a vector of lm_info_aix objects.
212 Return an empty option if the parsing failed. */
214 static gdb::optional<std::vector<lm_info_aix>>
215 solib_aix_parse_libraries (const char *library)
217 std::vector<lm_info_aix> result;
219 if (gdb_xml_parse_quick (_("aix library list"), "library-list-aix.dtd",
220 library_list_elements, library, &result) == 0)
221 return result;
223 return {};
226 #endif /* HAVE_LIBEXPAT */
228 /* Return the loader info for the given inferior (INF), or an empty
229 option if the list could not be computed.
231 Cache the result in per-inferior data, so as to avoid recomputing it
232 each time this function is called.
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. */
238 static gdb::optional<std::vector<lm_info_aix>> &
239 solib_aix_get_library_list (struct inferior *inf, const char *warning_msg)
241 struct solib_aix_inferior_data *data;
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;
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)
254 warning (_("%s (failed to read TARGET_OBJECT_LIBRARIES_AIX)"),
255 warning_msg);
256 return data->library_list;
259 solib_aix_debug_printf ("TARGET_OBJECT_LIBRARIES_AIX = %s",
260 library_document->data ());
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);
266 return data->library_list;
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.
273 Motivation:
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.
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).
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). */
293 static CORE_ADDR
294 solib_aix_bss_data_overlap (bfd *abfd)
296 struct bfd_section *data_sect, *bss_sect;
298 data_sect = bfd_get_section_by_name (abfd, ".data");
299 if (data_sect == NULL)
300 return 0; /* No overlap possible. */
302 bss_sect = bfd_get_section_by_name (abfd, ".bss");
303 if (bss_sect == NULL)
304 return 0; /* No overlap possible. */
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;
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));
318 return 0;
321 /* Implement the "relocate_section_addresses" target_so_ops method. */
323 static void
324 solib_aix_relocate_section_addresses (struct so_list *so,
325 struct target_section *sec)
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;
332 if (strcmp (section_name, ".text") == 0)
334 sec->addr = info->text_addr;
335 sec->endaddr = sec->addr + info->text_size;
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;
341 else if (strcmp (section_name, ".data") == 0)
343 sec->addr = info->data_addr;
344 sec->endaddr = sec->addr + info->data_size;
346 else if (strcmp (section_name, ".bss") == 0)
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;
359 if (data_sect != NULL)
360 data_offset = info->data_addr - bfd_section_vma (data_sect);
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);
366 else
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);
374 /* Implement the "free_so" target_so_ops method. */
376 static void
377 solib_aix_free_so (struct so_list *so)
379 lm_info_aix *li = (lm_info_aix *) so->lm_info;
381 solib_aix_debug_printf ("%s", so->so_name);
383 delete li;
386 /* Implement the "clear_solib" target_so_ops method. */
388 static void
389 solib_aix_clear_solib (void)
391 /* Nothing needed. */
394 /* Compute and return the OBJFILE's section_offset array, using
395 the associated loader info (INFO). */
397 static section_offsets
398 solib_aix_get_section_offsets (struct objfile *objfile,
399 lm_info_aix *info)
401 bfd *abfd = objfile->obfd;
403 section_offsets offsets (objfile->section_offsets.size ());
405 /* .text */
407 if (objfile->sect_index_text != -1)
409 struct bfd_section *sect
410 = objfile->sections[objfile->sect_index_text].the_bfd_section;
412 offsets[objfile->sect_index_text]
413 = info->text_addr + sect->filepos - bfd_section_vma (sect);
416 /* .data */
418 if (objfile->sect_index_data != -1)
420 struct bfd_section *sect
421 = objfile->sections[objfile->sect_index_data].the_bfd_section;
423 offsets[objfile->sect_index_data]
424 = info->data_addr - bfd_section_vma (sect);
427 /* .bss
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. */
433 if (objfile->sect_index_bss != -1
434 && objfile->sect_index_data != -1)
436 offsets[objfile->sect_index_bss]
437 = (offsets[objfile->sect_index_data]
438 + solib_aix_bss_data_overlap (abfd));
441 /* All other sections should not need relocation. */
443 return offsets;
446 /* Implement the "solib_create_inferior_hook" target_so_ops method. */
448 static void
449 solib_aix_solib_create_inferior_hook (int from_tty)
451 const char *warning_msg = "unable to relocate main executable";
453 /* We need to relocate the main executable... */
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. */
460 if (library_list->empty ())
462 warning (_("unable to relocate main executable (no info from loader)"));
463 return;
466 lm_info_aix &exec_info = (*library_list)[0];
467 if (current_program_space->symfile_object_file != NULL)
469 objfile *objf = current_program_space->symfile_object_file;
470 section_offsets offsets = solib_aix_get_section_offsets (objf,
471 &exec_info);
473 objfile_relocate (objf, offsets);
477 /* Implement the "current_sos" target_so_ops method. */
479 static struct so_list *
480 solib_aix_current_sos (void)
482 struct so_list *start = NULL, *last = NULL;
483 int ix;
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;
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++)
495 struct so_list *new_solib = XCNEW (struct so_list);
496 std::string so_name;
498 lm_info_aix &info = (*library_list)[ix];
499 if (info.member_name.empty ())
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;
507 else
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 ());
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);
523 /* Add it to the list. */
524 if (!start)
525 last = start = new_solib;
526 else
528 last->next = new_solib;
529 last = new_solib;
533 return start;
536 /* Implement the "open_symbol_file_object" target_so_ops method. */
538 static int
539 solib_aix_open_symbol_file_object (int from_tty)
541 return 0;
544 /* Implement the "in_dynsym_resolve_code" target_so_ops method. */
546 static int
547 solib_aix_in_dynsym_resolve_code (CORE_ADDR pc)
549 return 0;
552 /* Implement the "bfd_open" target_so_ops method. */
554 static gdb_bfd_ref_ptr
555 solib_aix_bfd_open (const char *pathname)
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.
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;
568 if (pathname[path_len - 1] != ')')
569 return solib_bfd_open (pathname);
571 /* Search for the associated parens. */
572 sep = strrchr (pathname, '(');
573 if (sep == NULL)
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);
581 filename_len = sep - pathname;
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));
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)
598 warning (_("Could not open `%s' as an executable file: %s"),
599 filename.c_str (), bfd_errmsg (bfd_get_error ()));
600 return NULL;
603 if (bfd_check_format (archive_bfd.get (), bfd_object))
604 return archive_bfd;
606 if (! bfd_check_format (archive_bfd.get (), bfd_archive))
608 warning (_("\"%s\": not in executable format: %s."),
609 filename.c_str (), bfd_errmsg (bfd_get_error ()));
610 return NULL;
613 gdb_bfd_ref_ptr object_bfd
614 (gdb_bfd_openr_next_archived_file (archive_bfd.get (), NULL));
615 while (object_bfd != NULL)
617 if (member_name == bfd_get_filename (object_bfd.get ()))
618 break;
620 object_bfd = gdb_bfd_openr_next_archived_file (archive_bfd.get (),
621 object_bfd.get ());
624 if (object_bfd == NULL)
626 warning (_("\"%s\": member \"%s\" missing."), filename.c_str (),
627 member_name.c_str ());
628 return NULL;
631 if (! bfd_check_format (object_bfd.get (), bfd_object))
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;
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 ());
648 return object_bfd;
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? */
655 static struct obj_section *
656 data_obj_section_from_objfile (struct objfile *objfile)
658 struct obj_section *osect;
660 ALL_OBJFILE_OSECTIONS (objfile, osect)
661 if (strcmp (bfd_section_name (osect->the_bfd_section), ".data") == 0)
662 return osect;
664 return NULL;
667 /* Return the TOC value corresponding to the given PC address,
668 or raise an error if the value could not be determined. */
670 CORE_ADDR
671 solib_aix_get_toc_value (CORE_ADDR pc)
673 struct obj_section *pc_osect = find_pc_section (pc);
674 struct obj_section *data_osect;
675 CORE_ADDR result;
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));
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));
688 result = data_osect->addr () + xcoff_get_toc_offset (pc_osect->objfile);
690 solib_aix_debug_printf ("pc=%s -> %s", core_addr_to_string (pc),
691 core_addr_to_string (result));
693 return result;
696 /* This module's normal_stop observer. */
698 static void
699 solib_aix_normal_stop_observer (struct bpstats *unused_1, int unused_2)
701 struct solib_aix_inferior_data *data
702 = get_solib_aix_inferior_data (current_inferior ());
704 /* The inferior execution has been resumed, and it just stopped
705 again. This means that the list of shared libraries may have
706 evolved. Reset our cached value. */
707 data->library_list.reset ();
710 /* Implements the "show debug aix-solib" command. */
712 static void
713 show_solib_aix_debug (struct ui_file *file, int from_tty,
714 struct cmd_list_element *c, const char *value)
716 fprintf_filtered (file, _("solib-aix debugging is %s.\n"), value);
719 /* The target_so_ops for AIX targets. */
720 struct target_so_ops solib_aix_so_ops;
722 void _initialize_solib_aix ();
723 void
724 _initialize_solib_aix ()
726 solib_aix_so_ops.relocate_section_addresses
727 = solib_aix_relocate_section_addresses;
728 solib_aix_so_ops.free_so = solib_aix_free_so;
729 solib_aix_so_ops.clear_solib = solib_aix_clear_solib;
730 solib_aix_so_ops.solib_create_inferior_hook
731 = solib_aix_solib_create_inferior_hook;
732 solib_aix_so_ops.current_sos = solib_aix_current_sos;
733 solib_aix_so_ops.open_symbol_file_object
734 = solib_aix_open_symbol_file_object;
735 solib_aix_so_ops.in_dynsym_resolve_code
736 = solib_aix_in_dynsym_resolve_code;
737 solib_aix_so_ops.bfd_open = solib_aix_bfd_open;
739 gdb::observers::normal_stop.attach (solib_aix_normal_stop_observer,
740 "solib-aix");
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);