1 /* Copyright (C) 2013-2019 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"
27 #include "observable.h"
29 #include "gdbsupport/scope-exit.h"
31 /* Variable controlling the output of the debugging traces for
33 static bool solib_aix_debug
;
35 /* Our private data in struct so_list. */
37 struct lm_info_aix
: public lm_info_base
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"
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
;
49 /* The address in inferior memory where the text section got mapped. */
50 CORE_ADDR text_addr
= 0;
52 /* The size of the text section, obtained via the loader data. */
53 ULONGEST text_size
= 0;
55 /* The address in inferior memory where the data section got mapped. */
56 CORE_ADDR data_addr
= 0;
58 /* The size of the data section, obtained via the loader data. */
59 ULONGEST data_size
= 0;
62 /* This module's per-inferior data. */
64 struct solib_aix_inferior_data
66 /* The list of shared libraries.
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
74 gdb::optional
<std::vector
<lm_info_aix
>> library_list
;
77 /* Key to our per-inferior data. */
78 static inferior_key
<solib_aix_inferior_data
> solib_aix_inferior_data_handle
;
80 /* Return this module's data for the given inferior.
81 If none is found, add a zero'ed one now. */
83 static struct solib_aix_inferior_data
*
84 get_solib_aix_inferior_data (struct inferior
*inf
)
86 struct solib_aix_inferior_data
*data
;
88 data
= solib_aix_inferior_data_handle
.get (inf
);
90 data
= solib_aix_inferior_data_handle
.emplace (inf
);
95 #if !defined(HAVE_LIBEXPAT)
97 /* Dummy implementation if XML support is not compiled in. */
99 static gdb::optional
<std::vector
<lm_info_aix
>>
100 solib_aix_parse_libraries (const char *library
)
102 static int have_warned
;
107 warning (_("Can not parse XML library list; XML support was disabled "
114 #else /* HAVE_LIBEXPAT */
116 #include "xml-support.h"
118 /* Handle the start of a <library> element. */
121 library_list_start_library (struct gdb_xml_parser
*parser
,
122 const struct gdb_xml_element
*element
,
124 std::vector
<gdb_xml_value
> &attributes
)
126 std::vector
<lm_info_aix
> *list
= (std::vector
<lm_info_aix
> *) user_data
;
128 struct gdb_xml_value
*attr
;
130 attr
= xml_find_attribute (attributes
, "name");
131 item
.filename
= (const char *) attr
->value
.get ();
133 attr
= xml_find_attribute (attributes
, "member");
135 item
.member_name
= (const char *) attr
->value
.get ();
137 attr
= xml_find_attribute (attributes
, "text_addr");
138 item
.text_addr
= * (ULONGEST
*) attr
->value
.get ();
140 attr
= xml_find_attribute (attributes
, "text_size");
141 item
.text_size
= * (ULONGEST
*) attr
->value
.get ();
143 attr
= xml_find_attribute (attributes
, "data_addr");
144 item
.data_addr
= * (ULONGEST
*) attr
->value
.get ();
146 attr
= xml_find_attribute (attributes
, "data_size");
147 item
.data_size
= * (ULONGEST
*) attr
->value
.get ();
149 list
->push_back (std::move (item
));
152 /* Handle the start of a <library-list-aix> element. */
155 library_list_start_list (struct gdb_xml_parser
*parser
,
156 const struct gdb_xml_element
*element
,
158 std::vector
<gdb_xml_value
> &attributes
)
161 = (char *) xml_find_attribute (attributes
, "version")->value
.get ();
163 if (strcmp (version
, "1.0") != 0)
164 gdb_xml_error (parser
,
165 _("Library list has unsupported version \"%s\""),
169 /* The allowed elements and attributes for an AIX library list
170 described in XML format. The root element is a <library-list-aix>. */
172 static const struct gdb_xml_attribute library_attributes
[] =
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
}
183 static const struct gdb_xml_element library_list_children
[] =
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
}
191 static const struct gdb_xml_attribute library_list_attributes
[] =
193 { "version", GDB_XML_AF_NONE
, NULL
, NULL
},
194 { NULL
, GDB_XML_AF_NONE
, NULL
, NULL
}
197 static const struct gdb_xml_element library_list_elements
[] =
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
}
204 /* Parse LIBRARY, a string containing the loader info in XML format,
205 and return a vector of lm_info_aix objects.
207 Return an empty option if the parsing failed. */
209 static gdb::optional
<std::vector
<lm_info_aix
>>
210 solib_aix_parse_libraries (const char *library
)
212 std::vector
<lm_info_aix
> result
;
214 if (gdb_xml_parse_quick (_("aix library list"), "library-list-aix.dtd",
215 library_list_elements
, library
, &result
) == 0)
221 #endif /* HAVE_LIBEXPAT */
223 /* Return the loader info for the given inferior (INF), or an empty
224 option if the list could not be computed.
226 Cache the result in per-inferior data, so as to avoid recomputing it
227 each time this function is called.
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. */
233 static gdb::optional
<std::vector
<lm_info_aix
>> &
234 solib_aix_get_library_list (struct inferior
*inf
, const char *warning_msg
)
236 struct solib_aix_inferior_data
*data
;
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
;
243 gdb::optional
<gdb::char_vector
> library_document
244 = target_read_stralloc (current_top_target (), TARGET_OBJECT_LIBRARIES_AIX
,
246 if (!library_document
&& warning_msg
!= NULL
)
248 warning (_("%s (failed to read TARGET_OBJECT_LIBRARIES_AIX)"),
250 return data
->library_list
;
254 fprintf_unfiltered (gdb_stdlog
,
255 "DEBUG: TARGET_OBJECT_LIBRARIES_AIX = \n%s\n",
256 library_document
->data ());
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
);
262 return data
->library_list
;
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.
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.
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
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). */
290 solib_aix_bss_data_overlap (bfd
*abfd
)
292 struct bfd_section
*data_sect
, *bss_sect
;
294 data_sect
= bfd_get_section_by_name (abfd
, ".data");
295 if (data_sect
== NULL
)
296 return 0; /* No overlap possible. */
298 bss_sect
= bfd_get_section_by_name (abfd
, ".bss");
299 if (bss_sect
== NULL
)
300 return 0; /* No overlap possible. */
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
))
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
));
317 /* Implement the "relocate_section_addresses" target_so_ops method. */
320 solib_aix_relocate_section_addresses (struct so_list
*so
,
321 struct target_section
*sec
)
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
;
328 if (strcmp (section_name
, ".text") == 0)
330 sec
->addr
= info
->text_addr
;
331 sec
->endaddr
= sec
->addr
+ info
->text_size
;
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
;
337 else if (strcmp (section_name
, ".data") == 0)
339 sec
->addr
= info
->data_addr
;
340 sec
->endaddr
= sec
->addr
+ info
->data_size
;
342 else if (strcmp (section_name
, ".bss") == 0)
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;
355 if (data_sect
!= NULL
)
356 data_offset
= info
->data_addr
- bfd_section_vma (data_sect
);
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
);
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
);
370 /* Implement the "free_so" target_so_ops method. */
373 solib_aix_free_so (struct so_list
*so
)
375 lm_info_aix
*li
= (lm_info_aix
*) so
->lm_info
;
378 fprintf_unfiltered (gdb_stdlog
, "DEBUG: solib_aix_free_so (%s)\n",
384 /* Implement the "clear_solib" target_so_ops method. */
387 solib_aix_clear_solib (void)
389 /* Nothing needed. */
392 /* Compute and return the OBJFILE's section_offset array, using
393 the associated loader info (INFO).
395 The resulting array is computed on the heap and must be
396 deallocated after use. */
398 static gdb::unique_xmalloc_ptr
<struct section_offsets
>
399 solib_aix_get_section_offsets (struct objfile
*objfile
,
402 bfd
*abfd
= objfile
->obfd
;
404 gdb::unique_xmalloc_ptr
<struct section_offsets
> offsets
405 (XCNEWVEC (struct section_offsets
, objfile
->num_sections
));
409 if (objfile
->sect_index_text
!= -1)
411 struct bfd_section
*sect
412 = objfile
->sections
[objfile
->sect_index_text
].the_bfd_section
;
414 offsets
->offsets
[objfile
->sect_index_text
]
415 = info
->text_addr
+ sect
->filepos
- bfd_section_vma (sect
);
420 if (objfile
->sect_index_data
!= -1)
422 struct bfd_section
*sect
423 = objfile
->sections
[objfile
->sect_index_data
].the_bfd_section
;
425 offsets
->offsets
[objfile
->sect_index_data
]
426 = info
->data_addr
- bfd_section_vma (sect
);
431 The offset of the .bss section should be identical to the offset
432 of the .data section. If no .data section (which seems hard to
433 believe it is possible), assume it is zero. */
435 if (objfile
->sect_index_bss
!= -1
436 && objfile
->sect_index_data
!= -1)
438 offsets
->offsets
[objfile
->sect_index_bss
]
439 = (offsets
->offsets
[objfile
->sect_index_data
]
440 + solib_aix_bss_data_overlap (abfd
));
443 /* All other sections should not need relocation. */
448 /* Implement the "solib_create_inferior_hook" target_so_ops method. */
451 solib_aix_solib_create_inferior_hook (int from_tty
)
453 const char *warning_msg
= "unable to relocate main executable";
455 /* We need to relocate the main executable... */
457 gdb::optional
<std::vector
<lm_info_aix
>> &library_list
458 = solib_aix_get_library_list (current_inferior (), warning_msg
);
459 if (!library_list
.has_value ())
460 return; /* Warning already printed. */
462 if (library_list
->empty ())
464 warning (_("unable to relocate main executable (no info from loader)"));
468 lm_info_aix
&exec_info
= (*library_list
)[0];
469 if (symfile_objfile
!= NULL
)
471 gdb::unique_xmalloc_ptr
<struct section_offsets
> offsets
472 = solib_aix_get_section_offsets (symfile_objfile
, &exec_info
);
474 objfile_relocate (symfile_objfile
, offsets
.get ());
478 /* Implement the "current_sos" target_so_ops method. */
480 static struct so_list
*
481 solib_aix_current_sos (void)
483 struct so_list
*start
= NULL
, *last
= NULL
;
486 gdb::optional
<std::vector
<lm_info_aix
>> &library_list
487 = solib_aix_get_library_list (current_inferior (), NULL
);
488 if (!library_list
.has_value ())
491 /* Build a struct so_list for each entry on the list.
492 We skip the first entry, since this is the entry corresponding
493 to the main executable, not a shared library. */
494 for (ix
= 1; ix
< library_list
->size (); ix
++)
496 struct so_list
*new_solib
= XCNEW (struct so_list
);
499 lm_info_aix
&info
= (*library_list
)[ix
];
500 if (info
.member_name
.empty ())
502 /* INFO.FILENAME is probably not an archive, but rather
503 a shared object. Unusual, but it should be possible
504 to link a program against a shared object directory,
505 without having to put it in an archive first. */
506 so_name
= info
.filename
;
510 /* This is the usual case on AIX, where the shared object
511 is a member of an archive. Create a synthetic so_name
512 that follows the same convention as AIX's ldd tool
513 (Eg: "/lib/libc.a(shr.o)"). */
514 so_name
= string_printf ("%s(%s)", info
.filename
.c_str (),
515 info
.member_name
.c_str ());
517 strncpy (new_solib
->so_original_name
, so_name
.c_str (),
518 SO_NAME_MAX_PATH_SIZE
- 1);
519 new_solib
->so_name
[SO_NAME_MAX_PATH_SIZE
- 1] = '\0';
520 memcpy (new_solib
->so_name
, new_solib
->so_original_name
,
521 SO_NAME_MAX_PATH_SIZE
);
522 new_solib
->lm_info
= new lm_info_aix (info
);
524 /* Add it to the list. */
526 last
= start
= new_solib
;
529 last
->next
= new_solib
;
537 /* Implement the "open_symbol_file_object" target_so_ops method. */
540 solib_aix_open_symbol_file_object (int from_tty
)
545 /* Implement the "in_dynsym_resolve_code" target_so_ops method. */
548 solib_aix_in_dynsym_resolve_code (CORE_ADDR pc
)
553 /* Implement the "bfd_open" target_so_ops method. */
555 static gdb_bfd_ref_ptr
556 solib_aix_bfd_open (const char *pathname
)
558 /* The pathname is actually a synthetic filename with the following
559 form: "/path/to/sharedlib(member.o)" (double-quotes excluded).
560 split this into archive name and member name.
562 FIXME: This is a little hacky. Perhaps we should provide access
563 to the solib's lm_info here? */
564 const int path_len
= strlen (pathname
);
569 if (pathname
[path_len
- 1] != ')')
570 return solib_bfd_open (pathname
);
572 /* Search for the associated parens. */
573 sep
= strrchr (pathname
, '(');
576 /* Should never happen, but recover as best as we can (trying
577 to open pathname without decoding, possibly leading to
578 a failure), rather than triggering an assert failure). */
579 warning (_("missing '(' in shared object pathname: %s"), pathname
);
580 return solib_bfd_open (pathname
);
582 filename_len
= sep
- pathname
;
584 std::string
filename (string_printf ("%.*s", filename_len
, pathname
));
585 std::string
member_name (string_printf ("%.*s", path_len
- filename_len
- 2,
588 /* Calling solib_find makes certain that sysroot path is set properly
589 if program has a dependency on .a archive and sysroot is set via
590 set sysroot command. */
591 gdb::unique_xmalloc_ptr
<char> found_pathname
592 = solib_find (filename
.c_str (), &found_file
);
593 if (found_pathname
== NULL
)
594 perror_with_name (pathname
);
595 gdb_bfd_ref_ptr
archive_bfd (solib_bfd_fopen (found_pathname
.get (),
597 if (archive_bfd
== NULL
)
599 warning (_("Could not open `%s' as an executable file: %s"),
600 filename
.c_str (), bfd_errmsg (bfd_get_error ()));
604 if (bfd_check_format (archive_bfd
.get (), bfd_object
))
607 if (! bfd_check_format (archive_bfd
.get (), bfd_archive
))
609 warning (_("\"%s\": not in executable format: %s."),
610 filename
.c_str (), bfd_errmsg (bfd_get_error ()));
614 gdb_bfd_ref_ptr object_bfd
615 (gdb_bfd_openr_next_archived_file (archive_bfd
.get (), NULL
));
616 while (object_bfd
!= NULL
)
618 if (member_name
== object_bfd
->filename
)
621 object_bfd
= gdb_bfd_openr_next_archived_file (archive_bfd
.get (),
625 if (object_bfd
== NULL
)
627 warning (_("\"%s\": member \"%s\" missing."), filename
.c_str (),
628 member_name
.c_str ());
632 if (! bfd_check_format (object_bfd
.get (), bfd_object
))
634 warning (_("%s(%s): not in object format: %s."),
635 filename
.c_str (), member_name
.c_str (),
636 bfd_errmsg (bfd_get_error ()));
640 /* Override the returned bfd's name with the name returned from solib_find
641 along with appended parenthesized member name in order to allow commands
642 listing all shared libraries to display. Otherwise, we would only be
643 displaying the name of the archive member object. */
644 bfd_set_filename (object_bfd
.get (),
646 bfd_get_filename (archive_bfd
.get ()),
652 /* Return the obj_section corresponding to OBJFILE's data section,
653 or NULL if not found. */
654 /* FIXME: Define in a more general location? */
656 static struct obj_section
*
657 data_obj_section_from_objfile (struct objfile
*objfile
)
659 struct obj_section
*osect
;
661 ALL_OBJFILE_OSECTIONS (objfile
, osect
)
662 if (strcmp (bfd_section_name (osect
->the_bfd_section
), ".data") == 0)
668 /* Return the TOC value corresponding to the given PC address,
669 or raise an error if the value could not be determined. */
672 solib_aix_get_toc_value (CORE_ADDR pc
)
674 struct obj_section
*pc_osect
= find_pc_section (pc
);
675 struct obj_section
*data_osect
;
678 if (pc_osect
== NULL
)
679 error (_("unable to find TOC entry for pc %s "
680 "(no section contains this PC)"),
681 core_addr_to_string (pc
));
683 data_osect
= data_obj_section_from_objfile (pc_osect
->objfile
);
684 if (data_osect
== NULL
)
685 error (_("unable to find TOC entry for pc %s "
686 "(%s has no data section)"),
687 core_addr_to_string (pc
), objfile_name (pc_osect
->objfile
));
689 result
= (obj_section_addr (data_osect
)
690 + xcoff_get_toc_offset (pc_osect
->objfile
));
692 fprintf_unfiltered (gdb_stdlog
,
693 "DEBUG: solib_aix_get_toc_value (pc=%s) -> %s\n",
694 core_addr_to_string (pc
),
695 core_addr_to_string (result
));
700 /* This module's normal_stop observer. */
703 solib_aix_normal_stop_observer (struct bpstats
*unused_1
, int unused_2
)
705 struct solib_aix_inferior_data
*data
706 = get_solib_aix_inferior_data (current_inferior ());
708 /* The inferior execution has been resumed, and it just stopped
709 again. This means that the list of shared libraries may have
710 evolved. Reset our cached value. */
711 data
->library_list
.reset ();
714 /* Implements the "show debug aix-solib" command. */
717 show_solib_aix_debug (struct ui_file
*file
, int from_tty
,
718 struct cmd_list_element
*c
, const char *value
)
720 fprintf_filtered (file
, _("solib-aix debugging is %s.\n"), value
);
723 /* The target_so_ops for AIX targets. */
724 struct target_so_ops solib_aix_so_ops
;
727 _initialize_solib_aix (void)
729 solib_aix_so_ops
.relocate_section_addresses
730 = solib_aix_relocate_section_addresses
;
731 solib_aix_so_ops
.free_so
= solib_aix_free_so
;
732 solib_aix_so_ops
.clear_solib
= solib_aix_clear_solib
;
733 solib_aix_so_ops
.solib_create_inferior_hook
734 = solib_aix_solib_create_inferior_hook
;
735 solib_aix_so_ops
.current_sos
= solib_aix_current_sos
;
736 solib_aix_so_ops
.open_symbol_file_object
737 = solib_aix_open_symbol_file_object
;
738 solib_aix_so_ops
.in_dynsym_resolve_code
739 = solib_aix_in_dynsym_resolve_code
;
740 solib_aix_so_ops
.bfd_open
= solib_aix_bfd_open
;
742 gdb::observers::normal_stop
.attach (solib_aix_normal_stop_observer
);
744 /* Debug this file's internals. */
745 add_setshow_boolean_cmd ("aix-solib", class_maintenance
,
746 &solib_aix_debug
, _("\
747 Control the debugging traces for the solib-aix module."), _("\
748 Show whether solib-aix debugging traces are enabled."), _("\
749 When on, solib-aix debugging traces are enabled."),
751 show_solib_aix_debug
,
752 &setdebuglist
, &showdebuglist
);