Fix accessing a method's fields from Python
[deliverable/binutils-gdb.git] / gdb / solib-aix.c
CommitLineData
b811d2c2 1/* Copyright (C) 2013-2020 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"
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"
76727919 27#include "observable.h"
4d1eb6b4 28#include "gdbcmd.h"
268a13a5 29#include "gdbsupport/scope-exit.h"
4d1eb6b4
JB
30
31/* Variable controlling the output of the debugging traces for
32 this module. */
491144b5 33static bool solib_aix_debug;
4d1eb6b4
JB
34
35/* Our private data in struct so_list. */
36
d0e449a1 37struct lm_info_aix : public lm_info_base
4d1eb6b4
JB
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). */
6c401f72 43 std::string filename;
4d1eb6b4
JB
44
45 /* The name of the shared object file with the actual dynamic
6c401f72
SM
46 loading dependency. This may be empty (Eg. main executable). */
47 std::string member_name;
4d1eb6b4
JB
48
49 /* The address in inferior memory where the text section got mapped. */
6c401f72 50 CORE_ADDR text_addr = 0;
4d1eb6b4
JB
51
52 /* The size of the text section, obtained via the loader data. */
6c401f72 53 ULONGEST text_size = 0;
4d1eb6b4
JB
54
55 /* The address in inferior memory where the data section got mapped. */
6c401f72 56 CORE_ADDR data_addr = 0;
4d1eb6b4
JB
57
58 /* The size of the data section, obtained via the loader data. */
6c401f72 59 ULONGEST data_size = 0;
4d1eb6b4
JB
60};
61
4d1eb6b4
JB
62/* This module's per-inferior data. */
63
64struct solib_aix_inferior_data
65{
a269fbf1 66 /* The list of shared libraries.
4d1eb6b4
JB
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. */
a269fbf1 74 gdb::optional<std::vector<lm_info_aix>> library_list;
4d1eb6b4
JB
75};
76
77/* Key to our per-inferior data. */
a269fbf1 78static inferior_key<solib_aix_inferior_data> solib_aix_inferior_data_handle;
4d1eb6b4
JB
79
80/* Return this module's data for the given inferior.
81 If none is found, add a zero'ed one now. */
82
83static struct solib_aix_inferior_data *
84get_solib_aix_inferior_data (struct inferior *inf)
85{
86 struct solib_aix_inferior_data *data;
87
a269fbf1 88 data = solib_aix_inferior_data_handle.get (inf);
4d1eb6b4 89 if (data == NULL)
a269fbf1 90 data = solib_aix_inferior_data_handle.emplace (inf);
4d1eb6b4
JB
91
92 return data;
93}
94
95#if !defined(HAVE_LIBEXPAT)
96
97/* Dummy implementation if XML support is not compiled in. */
98
a269fbf1 99static gdb::optional<std::vector<lm_info_aix>>
4d1eb6b4
JB
100solib_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 "
dda83cd7 108 "at compile time"));
4d1eb6b4
JB
109 }
110
a269fbf1 111 return {};
814a3ff7
JB
112}
113
4d1eb6b4
JB
114#else /* HAVE_LIBEXPAT */
115
116#include "xml-support.h"
117
118/* Handle the start of a <library> element. */
119
120static void
121library_list_start_library (struct gdb_xml_parser *parser,
122 const struct gdb_xml_element *element,
123 void *user_data,
4d0fdd9b 124 std::vector<gdb_xml_value> &attributes)
4d1eb6b4 125{
a269fbf1
TT
126 std::vector<lm_info_aix> *list = (std::vector<lm_info_aix> *) user_data;
127 lm_info_aix item;
4d1eb6b4
JB
128 struct gdb_xml_value *attr;
129
130 attr = xml_find_attribute (attributes, "name");
a269fbf1 131 item.filename = (const char *) attr->value.get ();
4d1eb6b4
JB
132
133 attr = xml_find_attribute (attributes, "member");
134 if (attr != NULL)
a269fbf1 135 item.member_name = (const char *) attr->value.get ();
4d1eb6b4
JB
136
137 attr = xml_find_attribute (attributes, "text_addr");
a269fbf1 138 item.text_addr = * (ULONGEST *) attr->value.get ();
4d1eb6b4
JB
139
140 attr = xml_find_attribute (attributes, "text_size");
a269fbf1 141 item.text_size = * (ULONGEST *) attr->value.get ();
4d1eb6b4
JB
142
143 attr = xml_find_attribute (attributes, "data_addr");
a269fbf1 144 item.data_addr = * (ULONGEST *) attr->value.get ();
4d1eb6b4
JB
145
146 attr = xml_find_attribute (attributes, "data_size");
a269fbf1 147 item.data_size = * (ULONGEST *) attr->value.get ();
4d1eb6b4 148
a269fbf1 149 list->push_back (std::move (item));
4d1eb6b4
JB
150}
151
8c56e112 152/* Handle the start of a <library-list-aix> element. */
4d1eb6b4
JB
153
154static void
155library_list_start_list (struct gdb_xml_parser *parser,
dda83cd7
SM
156 const struct gdb_xml_element *element,
157 void *user_data,
4d0fdd9b 158 std::vector<gdb_xml_value> &attributes)
4d1eb6b4 159{
4d0fdd9b
SM
160 char *version
161 = (char *) xml_find_attribute (attributes, "version")->value.get ();
4d1eb6b4
JB
162
163 if (strcmp (version, "1.0") != 0)
164 gdb_xml_error (parser,
dda83cd7
SM
165 _("Library list has unsupported version \"%s\""),
166 version);
4d1eb6b4
JB
167}
168
4d1eb6b4 169/* The allowed elements and attributes for an AIX library list
8c56e112 170 described in XML format. The root element is a <library-list-aix>. */
4d1eb6b4
JB
171
172static 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
183static 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
191static 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
197static const struct gdb_xml_element library_list_elements[] =
198{
8c56e112 199 { "library-list-aix", library_list_attributes, library_list_children,
4d1eb6b4
JB
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,
a269fbf1 205 and return a vector of lm_info_aix objects.
4d1eb6b4 206
a269fbf1 207 Return an empty option if the parsing failed. */
4d1eb6b4 208
a269fbf1 209static gdb::optional<std::vector<lm_info_aix>>
4d1eb6b4
JB
210solib_aix_parse_libraries (const char *library)
211{
a269fbf1 212 std::vector<lm_info_aix> result;
4d1eb6b4
JB
213
214 if (gdb_xml_parse_quick (_("aix library list"), "library-list-aix.dtd",
a269fbf1
TT
215 library_list_elements, library, &result) == 0)
216 return result;
4d1eb6b4 217
a269fbf1 218 return {};
4d1eb6b4
JB
219}
220
221#endif /* HAVE_LIBEXPAT */
222
a269fbf1
TT
223/* Return the loader info for the given inferior (INF), or an empty
224 option if the list could not be computed.
4d1eb6b4
JB
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
a269fbf1 233static gdb::optional<std::vector<lm_info_aix>> &
4d1eb6b4
JB
234solib_aix_get_library_list (struct inferior *inf, const char *warning_msg)
235{
236 struct solib_aix_inferior_data *data;
4d1eb6b4
JB
237
238 /* If already computed, return the cached value. */
239 data = get_solib_aix_inferior_data (inf);
a269fbf1 240 if (data->library_list.has_value ())
4d1eb6b4
JB
241 return data->library_list;
242
9018be22 243 gdb::optional<gdb::char_vector> library_document
8b88a78e 244 = target_read_stralloc (current_top_target (), TARGET_OBJECT_LIBRARIES_AIX,
b7b030ad 245 NULL);
9018be22 246 if (!library_document && warning_msg != NULL)
4d1eb6b4 247 {
ff99b71b 248 warning (_("%s (failed to read TARGET_OBJECT_LIBRARIES_AIX)"),
4d1eb6b4 249 warning_msg);
a269fbf1 250 return data->library_list;
4d1eb6b4 251 }
4d1eb6b4
JB
252
253 if (solib_aix_debug)
254 fprintf_unfiltered (gdb_stdlog,
ff99b71b 255 "DEBUG: TARGET_OBJECT_LIBRARIES_AIX = \n%s\n",
9018be22 256 library_document->data ());
4d1eb6b4 257
9018be22 258 data->library_list = solib_aix_parse_libraries (library_document->data ());
a269fbf1
TT
259 if (!data->library_list.has_value () && warning_msg != NULL)
260 warning (_("%s (missing XML support?)"), warning_msg);
4d1eb6b4 261
4d1eb6b4
JB
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
289static CORE_ADDR
290solib_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). */
fd361982 306 if (bfd_section_vma (bss_sect) < bfd_section_vma (data_sect))
4d1eb6b4
JB
307 return 0;
308
fd361982
AM
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));
4d1eb6b4
JB
313
314 return 0;
315}
316
317/* Implement the "relocate_section_addresses" target_so_ops method. */
318
319static void
320solib_aix_relocate_section_addresses (struct so_list *so,
321 struct target_section *sec)
322{
4d1eb6b4 323 struct bfd_section *bfd_sect = sec->the_bfd_section;
57e6060e 324 bfd *abfd = bfd_sect->owner;
fd361982 325 const char *section_name = bfd_section_name (bfd_sect);
d0e449a1 326 lm_info_aix *info = (lm_info_aix *) so->lm_info;
4d1eb6b4
JB
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 {
060cfbef
JB
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)
fd361982 356 data_offset = info->data_addr - bfd_section_vma (data_sect);
060cfbef 357
fd361982 358 sec->addr = bfd_section_vma (bfd_sect) + data_offset;
4d1eb6b4 359 sec->addr += solib_aix_bss_data_overlap (abfd);
fd361982 360 sec->endaddr = sec->addr + bfd_section_size (bfd_sect);
4d1eb6b4
JB
361 }
362 else
363 {
364 /* All other sections should not be relocated. */
fd361982
AM
365 sec->addr = bfd_section_vma (bfd_sect);
366 sec->endaddr = sec->addr + bfd_section_size (bfd_sect);
4d1eb6b4
JB
367 }
368}
369
370/* Implement the "free_so" target_so_ops method. */
371
372static void
373solib_aix_free_so (struct so_list *so)
374{
6c401f72
SM
375 lm_info_aix *li = (lm_info_aix *) so->lm_info;
376
4d1eb6b4
JB
377 if (solib_aix_debug)
378 fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_so (%s)\n",
379 so->so_name);
6c401f72
SM
380
381 delete li;
4d1eb6b4
JB
382}
383
384/* Implement the "clear_solib" target_so_ops method. */
385
386static void
387solib_aix_clear_solib (void)
388{
389 /* Nothing needed. */
390}
391
392/* Compute and return the OBJFILE's section_offset array, using
6a053cb1 393 the associated loader info (INFO). */
4d1eb6b4 394
6a053cb1 395static section_offsets
4d1eb6b4 396solib_aix_get_section_offsets (struct objfile *objfile,
d0e449a1 397 lm_info_aix *info)
4d1eb6b4 398{
4d1eb6b4 399 bfd *abfd = objfile->obfd;
4d1eb6b4 400
6a053cb1 401 section_offsets offsets (objfile->section_offsets.size ());
4d1eb6b4
JB
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
6a053cb1 410 offsets[objfile->sect_index_text]
fd361982 411 = info->text_addr + sect->filepos - bfd_section_vma (sect);
4d1eb6b4
JB
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
6a053cb1 421 offsets[objfile->sect_index_data]
fd361982 422 = info->data_addr - bfd_section_vma (sect);
4d1eb6b4
JB
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 {
6a053cb1
TT
434 offsets[objfile->sect_index_bss]
435 = (offsets[objfile->sect_index_data]
4d1eb6b4
JB
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
446static void
447solib_aix_solib_create_inferior_hook (int from_tty)
448{
449 const char *warning_msg = "unable to relocate main executable";
4d1eb6b4
JB
450
451 /* We need to relocate the main executable... */
452
a269fbf1
TT
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 ())
4d1eb6b4
JB
456 return; /* Warning already printed. */
457
a269fbf1 458 if (library_list->empty ())
4d1eb6b4
JB
459 {
460 warning (_("unable to relocate main executable (no info from loader)"));
461 return;
462 }
463
a269fbf1 464 lm_info_aix &exec_info = (*library_list)[0];
a42d7dd8 465 if (current_program_space->symfile_object_file != NULL)
4d1eb6b4 466 {
a42d7dd8
TT
467 objfile *objf = current_program_space->symfile_object_file;
468 section_offsets offsets = solib_aix_get_section_offsets (objf,
469 &exec_info);
4d1eb6b4 470
a42d7dd8 471 objfile_relocate (objf, offsets);
4d1eb6b4
JB
472 }
473}
474
4d1eb6b4
JB
475/* Implement the "current_sos" target_so_ops method. */
476
477static struct so_list *
478solib_aix_current_sos (void)
479{
480 struct so_list *start = NULL, *last = NULL;
4d1eb6b4
JB
481 int ix;
482
a269fbf1
TT
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 ())
4d1eb6b4
JB
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. */
a269fbf1 491 for (ix = 1; ix < library_list->size (); ix++)
4d1eb6b4 492 {
41bf6aca 493 struct so_list *new_solib = XCNEW (struct so_list);
6c401f72 494 std::string so_name;
4d1eb6b4 495
a269fbf1
TT
496 lm_info_aix &info = (*library_list)[ix];
497 if (info.member_name.empty ())
4d1eb6b4 498 {
a269fbf1 499 /* INFO.FILENAME is probably not an archive, but rather
4d1eb6b4
JB
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. */
a269fbf1 503 so_name = info.filename;
4d1eb6b4
JB
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)"). */
a269fbf1
TT
511 so_name = string_printf ("%s(%s)", info.filename.c_str (),
512 info.member_name.c_str ());
4d1eb6b4 513 }
6c401f72 514 strncpy (new_solib->so_original_name, so_name.c_str (),
4d1eb6b4
JB
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);
a269fbf1 519 new_solib->lm_info = new lm_info_aix (info);
4d1eb6b4
JB
520
521 /* Add it to the list. */
522 if (!start)
dda83cd7 523 last = start = new_solib;
4d1eb6b4 524 else
dda83cd7
SM
525 {
526 last->next = new_solib;
527 last = new_solib;
528 }
4d1eb6b4
JB
529 }
530
531 return start;
532}
533
534/* Implement the "open_symbol_file_object" target_so_ops method. */
535
536static int
bf469271 537solib_aix_open_symbol_file_object (int from_tty)
4d1eb6b4
JB
538{
539 return 0;
540}
541
542/* Implement the "in_dynsym_resolve_code" target_so_ops method. */
543
544static int
545solib_aix_in_dynsym_resolve_code (CORE_ADDR pc)
546{
547 return 0;
548}
549
550/* Implement the "bfd_open" target_so_ops method. */
551
192b62ce 552static gdb_bfd_ref_ptr
692d6f97 553solib_aix_bfd_open (const char *pathname)
4d1eb6b4
JB
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);
692d6f97 562 const char *sep;
4d1eb6b4 563 int filename_len;
754c39c2 564 int found_file;
4d1eb6b4
JB
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
192b62ce
TT
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));
4d1eb6b4 584
754c39c2
UW
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. */
797bc1cb
TT
588 gdb::unique_xmalloc_ptr<char> found_pathname
589 = solib_find (filename.c_str (), &found_file);
754c39c2
UW
590 if (found_pathname == NULL)
591 perror_with_name (pathname);
797bc1cb
TT
592 gdb_bfd_ref_ptr archive_bfd (solib_bfd_fopen (found_pathname.get (),
593 found_file));
4d1eb6b4
JB
594 if (archive_bfd == NULL)
595 {
596 warning (_("Could not open `%s' as an executable file: %s"),
192b62ce 597 filename.c_str (), bfd_errmsg (bfd_get_error ()));
4d1eb6b4
JB
598 return NULL;
599 }
600
192b62ce
TT
601 if (bfd_check_format (archive_bfd.get (), bfd_object))
602 return archive_bfd;
4d1eb6b4 603
192b62ce 604 if (! bfd_check_format (archive_bfd.get (), bfd_archive))
4d1eb6b4
JB
605 {
606 warning (_("\"%s\": not in executable format: %s."),
192b62ce 607 filename.c_str (), bfd_errmsg (bfd_get_error ()));
4d1eb6b4
JB
608 return NULL;
609 }
610
192b62ce
TT
611 gdb_bfd_ref_ptr object_bfd
612 (gdb_bfd_openr_next_archived_file (archive_bfd.get (), NULL));
4d1eb6b4
JB
613 while (object_bfd != NULL)
614 {
c7e97679 615 if (member_name == bfd_get_filename (object_bfd.get ()))
4d1eb6b4
JB
616 break;
617
192b62ce
TT
618 object_bfd = gdb_bfd_openr_next_archived_file (archive_bfd.get (),
619 object_bfd.get ());
4d1eb6b4
JB
620 }
621
622 if (object_bfd == NULL)
623 {
192b62ce
TT
624 warning (_("\"%s\": member \"%s\" missing."), filename.c_str (),
625 member_name.c_str ());
4d1eb6b4
JB
626 return NULL;
627 }
628
192b62ce 629 if (! bfd_check_format (object_bfd.get (), bfd_object))
4d1eb6b4
JB
630 {
631 warning (_("%s(%s): not in object format: %s."),
192b62ce
TT
632 filename.c_str (), member_name.c_str (),
633 bfd_errmsg (bfd_get_error ()));
4d1eb6b4
JB
634 return NULL;
635 }
636
754c39c2
UW
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. */
7b958a48
AM
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 ());
b030cf11 645
4d1eb6b4
JB
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
653static struct obj_section *
654data_obj_section_from_objfile (struct objfile *objfile)
655{
656 struct obj_section *osect;
657
658 ALL_OBJFILE_OSECTIONS (objfile, osect)
fd361982 659 if (strcmp (bfd_section_name (osect->the_bfd_section), ".data") == 0)
4d1eb6b4
JB
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
668CORE_ADDR
669solib_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)"),
4262abfb 684 core_addr_to_string (pc), objfile_name (pc_osect->objfile));
4d1eb6b4
JB
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
699static void
700solib_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. */
a269fbf1 708 data->library_list.reset ();
4d1eb6b4
JB
709}
710
711/* Implements the "show debug aix-solib" command. */
712
713static void
714show_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. */
721struct target_so_ops solib_aix_so_ops;
722
6c265988 723void _initialize_solib_aix ();
4d1eb6b4 724void
6c265988 725_initialize_solib_aix ()
4d1eb6b4
JB
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;
4d1eb6b4
JB
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
76727919 740 gdb::observers::normal_stop.attach (solib_aix_normal_stop_observer);
4d1eb6b4
JB
741
742 /* Debug this file's internals. */
743 add_setshow_boolean_cmd ("aix-solib", class_maintenance,
744 &solib_aix_debug, _("\
745Control the debugging traces for the solib-aix module."), _("\
746Show whether solib-aix debugging traces are enabled."), _("\
747When on, solib-aix debugging traces are enabled."),
dda83cd7
SM
748 NULL,
749 show_solib_aix_debug,
750 &setdebuglist, &showdebuglist);
4d1eb6b4 751}
This page took 0.889673 seconds and 4 git commands to generate.