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