gdb/remote: Use true/false instead of 1/0
[deliverable/binutils-gdb.git] / gdb / solib-aix.c
CommitLineData
3666a048 1/* Copyright (C) 2013-2021 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 34
eef401dc
SM
35/* Print an "aix-solib" debug statement. */
36
37#define solib_aix_debug_printf(fmt, ...) \
38 debug_prefixed_printf_cond (solib_aix_debug, "aix-solib",fmt, ##__VA_ARGS__)
39
4d1eb6b4
JB
40/* Our private data in struct so_list. */
41
d0e449a1 42struct lm_info_aix : public lm_info_base
4d1eb6b4
JB
43{
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). */
6c401f72 48 std::string filename;
4d1eb6b4
JB
49
50 /* The name of the shared object file with the actual dynamic
6c401f72
SM
51 loading dependency. This may be empty (Eg. main executable). */
52 std::string member_name;
4d1eb6b4
JB
53
54 /* The address in inferior memory where the text section got mapped. */
6c401f72 55 CORE_ADDR text_addr = 0;
4d1eb6b4
JB
56
57 /* The size of the text section, obtained via the loader data. */
6c401f72 58 ULONGEST text_size = 0;
4d1eb6b4
JB
59
60 /* The address in inferior memory where the data section got mapped. */
6c401f72 61 CORE_ADDR data_addr = 0;
4d1eb6b4
JB
62
63 /* The size of the data section, obtained via the loader data. */
6c401f72 64 ULONGEST data_size = 0;
4d1eb6b4
JB
65};
66
4d1eb6b4
JB
67/* This module's per-inferior data. */
68
69struct solib_aix_inferior_data
70{
a269fbf1 71 /* The list of shared libraries.
4d1eb6b4
JB
72
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. */
a269fbf1 79 gdb::optional<std::vector<lm_info_aix>> library_list;
4d1eb6b4
JB
80};
81
82/* Key to our per-inferior data. */
a269fbf1 83static inferior_key<solib_aix_inferior_data> solib_aix_inferior_data_handle;
4d1eb6b4
JB
84
85/* Return this module's data for the given inferior.
86 If none is found, add a zero'ed one now. */
87
88static struct solib_aix_inferior_data *
89get_solib_aix_inferior_data (struct inferior *inf)
90{
91 struct solib_aix_inferior_data *data;
92
a269fbf1 93 data = solib_aix_inferior_data_handle.get (inf);
4d1eb6b4 94 if (data == NULL)
a269fbf1 95 data = solib_aix_inferior_data_handle.emplace (inf);
4d1eb6b4
JB
96
97 return data;
98}
99
100#if !defined(HAVE_LIBEXPAT)
101
102/* Dummy implementation if XML support is not compiled in. */
103
a269fbf1 104static gdb::optional<std::vector<lm_info_aix>>
4d1eb6b4
JB
105solib_aix_parse_libraries (const char *library)
106{
107 static int have_warned;
108
109 if (!have_warned)
110 {
111 have_warned = 1;
112 warning (_("Can not parse XML library list; XML support was disabled "
dda83cd7 113 "at compile time"));
4d1eb6b4
JB
114 }
115
a269fbf1 116 return {};
814a3ff7
JB
117}
118
4d1eb6b4
JB
119#else /* HAVE_LIBEXPAT */
120
121#include "xml-support.h"
122
123/* Handle the start of a <library> element. */
124
125static void
126library_list_start_library (struct gdb_xml_parser *parser,
127 const struct gdb_xml_element *element,
128 void *user_data,
4d0fdd9b 129 std::vector<gdb_xml_value> &attributes)
4d1eb6b4 130{
a269fbf1
TT
131 std::vector<lm_info_aix> *list = (std::vector<lm_info_aix> *) user_data;
132 lm_info_aix item;
4d1eb6b4
JB
133 struct gdb_xml_value *attr;
134
135 attr = xml_find_attribute (attributes, "name");
a269fbf1 136 item.filename = (const char *) attr->value.get ();
4d1eb6b4
JB
137
138 attr = xml_find_attribute (attributes, "member");
139 if (attr != NULL)
a269fbf1 140 item.member_name = (const char *) attr->value.get ();
4d1eb6b4
JB
141
142 attr = xml_find_attribute (attributes, "text_addr");
a269fbf1 143 item.text_addr = * (ULONGEST *) attr->value.get ();
4d1eb6b4
JB
144
145 attr = xml_find_attribute (attributes, "text_size");
a269fbf1 146 item.text_size = * (ULONGEST *) attr->value.get ();
4d1eb6b4
JB
147
148 attr = xml_find_attribute (attributes, "data_addr");
a269fbf1 149 item.data_addr = * (ULONGEST *) attr->value.get ();
4d1eb6b4
JB
150
151 attr = xml_find_attribute (attributes, "data_size");
a269fbf1 152 item.data_size = * (ULONGEST *) attr->value.get ();
4d1eb6b4 153
a269fbf1 154 list->push_back (std::move (item));
4d1eb6b4
JB
155}
156
8c56e112 157/* Handle the start of a <library-list-aix> element. */
4d1eb6b4
JB
158
159static void
160library_list_start_list (struct gdb_xml_parser *parser,
dda83cd7
SM
161 const struct gdb_xml_element *element,
162 void *user_data,
4d0fdd9b 163 std::vector<gdb_xml_value> &attributes)
4d1eb6b4 164{
4d0fdd9b
SM
165 char *version
166 = (char *) xml_find_attribute (attributes, "version")->value.get ();
4d1eb6b4
JB
167
168 if (strcmp (version, "1.0") != 0)
169 gdb_xml_error (parser,
dda83cd7
SM
170 _("Library list has unsupported version \"%s\""),
171 version);
4d1eb6b4
JB
172}
173
4d1eb6b4 174/* The allowed elements and attributes for an AIX library list
8c56e112 175 described in XML format. The root element is a <library-list-aix>. */
4d1eb6b4
JB
176
177static const struct gdb_xml_attribute library_attributes[] =
178{
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 }
186};
187
188static const struct gdb_xml_element library_list_children[] =
189{
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 }
194};
195
196static const struct gdb_xml_attribute library_list_attributes[] =
197{
198 { "version", GDB_XML_AF_NONE, NULL, NULL },
199 { NULL, GDB_XML_AF_NONE, NULL, NULL }
200};
201
202static const struct gdb_xml_element library_list_elements[] =
203{
8c56e112 204 { "library-list-aix", library_list_attributes, library_list_children,
4d1eb6b4
JB
205 GDB_XML_EF_NONE, library_list_start_list, NULL },
206 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
207};
208
209/* Parse LIBRARY, a string containing the loader info in XML format,
a269fbf1 210 and return a vector of lm_info_aix objects.
4d1eb6b4 211
a269fbf1 212 Return an empty option if the parsing failed. */
4d1eb6b4 213
a269fbf1 214static gdb::optional<std::vector<lm_info_aix>>
4d1eb6b4
JB
215solib_aix_parse_libraries (const char *library)
216{
a269fbf1 217 std::vector<lm_info_aix> result;
4d1eb6b4
JB
218
219 if (gdb_xml_parse_quick (_("aix library list"), "library-list-aix.dtd",
a269fbf1
TT
220 library_list_elements, library, &result) == 0)
221 return result;
4d1eb6b4 222
a269fbf1 223 return {};
4d1eb6b4
JB
224}
225
226#endif /* HAVE_LIBEXPAT */
227
a269fbf1
TT
228/* Return the loader info for the given inferior (INF), or an empty
229 option if the list could not be computed.
4d1eb6b4
JB
230
231 Cache the result in per-inferior data, so as to avoid recomputing it
232 each time this function is called.
233
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. */
237
a269fbf1 238static gdb::optional<std::vector<lm_info_aix>> &
4d1eb6b4
JB
239solib_aix_get_library_list (struct inferior *inf, const char *warning_msg)
240{
241 struct solib_aix_inferior_data *data;
4d1eb6b4
JB
242
243 /* If already computed, return the cached value. */
244 data = get_solib_aix_inferior_data (inf);
a269fbf1 245 if (data->library_list.has_value ())
4d1eb6b4
JB
246 return data->library_list;
247
9018be22 248 gdb::optional<gdb::char_vector> library_document
328d42d8
SM
249 = target_read_stralloc (current_inferior ()->top_target (),
250 TARGET_OBJECT_LIBRARIES_AIX,
b7b030ad 251 NULL);
9018be22 252 if (!library_document && warning_msg != NULL)
4d1eb6b4 253 {
ff99b71b 254 warning (_("%s (failed to read TARGET_OBJECT_LIBRARIES_AIX)"),
4d1eb6b4 255 warning_msg);
a269fbf1 256 return data->library_list;
4d1eb6b4 257 }
4d1eb6b4 258
eef401dc
SM
259 solib_aix_debug_printf ("TARGET_OBJECT_LIBRARIES_AIX = %s",
260 library_document->data ());
4d1eb6b4 261
9018be22 262 data->library_list = solib_aix_parse_libraries (library_document->data ());
a269fbf1
TT
263 if (!data->library_list.has_value () && warning_msg != NULL)
264 warning (_("%s (missing XML support?)"), warning_msg);
4d1eb6b4 265
4d1eb6b4
JB
266 return data->library_list;
267}
268
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.
272
273 Motivation:
274
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.
279
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).
287
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). */
292
293static CORE_ADDR
294solib_aix_bss_data_overlap (bfd *abfd)
295{
296 struct bfd_section *data_sect, *bss_sect;
297
298 data_sect = bfd_get_section_by_name (abfd, ".data");
299 if (data_sect == NULL)
300 return 0; /* No overlap possible. */
301
302 bss_sect = bfd_get_section_by_name (abfd, ".bss");
303 if (bss_sect == NULL)
304 return 0; /* No overlap possible. */
305
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). */
fd361982 310 if (bfd_section_vma (bss_sect) < bfd_section_vma (data_sect))
4d1eb6b4
JB
311 return 0;
312
fd361982
AM
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));
4d1eb6b4
JB
317
318 return 0;
319}
320
321/* Implement the "relocate_section_addresses" target_so_ops method. */
322
323static void
324solib_aix_relocate_section_addresses (struct so_list *so,
325 struct target_section *sec)
326{
4d1eb6b4 327 struct bfd_section *bfd_sect = sec->the_bfd_section;
57e6060e 328 bfd *abfd = bfd_sect->owner;
fd361982 329 const char *section_name = bfd_section_name (bfd_sect);
d0e449a1 330 lm_info_aix *info = (lm_info_aix *) so->lm_info;
4d1eb6b4
JB
331
332 if (strcmp (section_name, ".text") == 0)
333 {
334 sec->addr = info->text_addr;
335 sec->endaddr = sec->addr + info->text_size;
336
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;
340 }
341 else if (strcmp (section_name, ".data") == 0)
342 {
343 sec->addr = info->data_addr;
344 sec->endaddr = sec->addr + info->data_size;
345 }
346 else if (strcmp (section_name, ".bss") == 0)
347 {
060cfbef
JB
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;
358
359 if (data_sect != NULL)
fd361982 360 data_offset = info->data_addr - bfd_section_vma (data_sect);
060cfbef 361
fd361982 362 sec->addr = bfd_section_vma (bfd_sect) + data_offset;
4d1eb6b4 363 sec->addr += solib_aix_bss_data_overlap (abfd);
fd361982 364 sec->endaddr = sec->addr + bfd_section_size (bfd_sect);
4d1eb6b4
JB
365 }
366 else
367 {
368 /* All other sections should not be relocated. */
fd361982
AM
369 sec->addr = bfd_section_vma (bfd_sect);
370 sec->endaddr = sec->addr + bfd_section_size (bfd_sect);
4d1eb6b4
JB
371 }
372}
373
374/* Implement the "free_so" target_so_ops method. */
375
376static void
377solib_aix_free_so (struct so_list *so)
378{
6c401f72
SM
379 lm_info_aix *li = (lm_info_aix *) so->lm_info;
380
eef401dc 381 solib_aix_debug_printf ("%s", so->so_name);
6c401f72
SM
382
383 delete li;
4d1eb6b4
JB
384}
385
386/* Implement the "clear_solib" target_so_ops method. */
387
388static void
389solib_aix_clear_solib (void)
390{
391 /* Nothing needed. */
392}
393
394/* Compute and return the OBJFILE's section_offset array, using
6a053cb1 395 the associated loader info (INFO). */
4d1eb6b4 396
6a053cb1 397static section_offsets
4d1eb6b4 398solib_aix_get_section_offsets (struct objfile *objfile,
d0e449a1 399 lm_info_aix *info)
4d1eb6b4 400{
4d1eb6b4 401 bfd *abfd = objfile->obfd;
4d1eb6b4 402
6a053cb1 403 section_offsets offsets (objfile->section_offsets.size ());
4d1eb6b4
JB
404
405 /* .text */
406
407 if (objfile->sect_index_text != -1)
408 {
409 struct bfd_section *sect
410 = objfile->sections[objfile->sect_index_text].the_bfd_section;
411
6a053cb1 412 offsets[objfile->sect_index_text]
fd361982 413 = info->text_addr + sect->filepos - bfd_section_vma (sect);
4d1eb6b4
JB
414 }
415
416 /* .data */
417
418 if (objfile->sect_index_data != -1)
419 {
420 struct bfd_section *sect
421 = objfile->sections[objfile->sect_index_data].the_bfd_section;
422
6a053cb1 423 offsets[objfile->sect_index_data]
fd361982 424 = info->data_addr - bfd_section_vma (sect);
4d1eb6b4
JB
425 }
426
427 /* .bss
428
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. */
432
433 if (objfile->sect_index_bss != -1
434 && objfile->sect_index_data != -1)
435 {
6a053cb1
TT
436 offsets[objfile->sect_index_bss]
437 = (offsets[objfile->sect_index_data]
4d1eb6b4
JB
438 + solib_aix_bss_data_overlap (abfd));
439 }
440
441 /* All other sections should not need relocation. */
442
443 return offsets;
444}
445
446/* Implement the "solib_create_inferior_hook" target_so_ops method. */
447
448static void
449solib_aix_solib_create_inferior_hook (int from_tty)
450{
451 const char *warning_msg = "unable to relocate main executable";
4d1eb6b4
JB
452
453 /* We need to relocate the main executable... */
454
a269fbf1
TT
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 ())
4d1eb6b4
JB
458 return; /* Warning already printed. */
459
a269fbf1 460 if (library_list->empty ())
4d1eb6b4
JB
461 {
462 warning (_("unable to relocate main executable (no info from loader)"));
463 return;
464 }
465
a269fbf1 466 lm_info_aix &exec_info = (*library_list)[0];
a42d7dd8 467 if (current_program_space->symfile_object_file != NULL)
4d1eb6b4 468 {
a42d7dd8
TT
469 objfile *objf = current_program_space->symfile_object_file;
470 section_offsets offsets = solib_aix_get_section_offsets (objf,
471 &exec_info);
4d1eb6b4 472
a42d7dd8 473 objfile_relocate (objf, offsets);
4d1eb6b4
JB
474 }
475}
476
4d1eb6b4
JB
477/* Implement the "current_sos" target_so_ops method. */
478
479static struct so_list *
480solib_aix_current_sos (void)
481{
482 struct so_list *start = NULL, *last = NULL;
4d1eb6b4
JB
483 int ix;
484
a269fbf1
TT
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 ())
4d1eb6b4
JB
488 return NULL;
489
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. */
a269fbf1 493 for (ix = 1; ix < library_list->size (); ix++)
4d1eb6b4 494 {
41bf6aca 495 struct so_list *new_solib = XCNEW (struct so_list);
6c401f72 496 std::string so_name;
4d1eb6b4 497
a269fbf1
TT
498 lm_info_aix &info = (*library_list)[ix];
499 if (info.member_name.empty ())
4d1eb6b4 500 {
a269fbf1 501 /* INFO.FILENAME is probably not an archive, but rather
4d1eb6b4
JB
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. */
a269fbf1 505 so_name = info.filename;
4d1eb6b4
JB
506 }
507 else
508 {
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)"). */
a269fbf1
TT
513 so_name = string_printf ("%s(%s)", info.filename.c_str (),
514 info.member_name.c_str ());
4d1eb6b4 515 }
6c401f72 516 strncpy (new_solib->so_original_name, so_name.c_str (),
4d1eb6b4
JB
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);
a269fbf1 521 new_solib->lm_info = new lm_info_aix (info);
4d1eb6b4
JB
522
523 /* Add it to the list. */
524 if (!start)
dda83cd7 525 last = start = new_solib;
4d1eb6b4 526 else
dda83cd7
SM
527 {
528 last->next = new_solib;
529 last = new_solib;
530 }
4d1eb6b4
JB
531 }
532
533 return start;
534}
535
536/* Implement the "open_symbol_file_object" target_so_ops method. */
537
538static int
bf469271 539solib_aix_open_symbol_file_object (int from_tty)
4d1eb6b4
JB
540{
541 return 0;
542}
543
544/* Implement the "in_dynsym_resolve_code" target_so_ops method. */
545
546static int
547solib_aix_in_dynsym_resolve_code (CORE_ADDR pc)
548{
549 return 0;
550}
551
552/* Implement the "bfd_open" target_so_ops method. */
553
192b62ce 554static gdb_bfd_ref_ptr
692d6f97 555solib_aix_bfd_open (const char *pathname)
4d1eb6b4
JB
556{
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.
560
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);
692d6f97 564 const char *sep;
4d1eb6b4 565 int filename_len;
754c39c2 566 int found_file;
4d1eb6b4
JB
567
568 if (pathname[path_len - 1] != ')')
569 return solib_bfd_open (pathname);
570
571 /* Search for the associated parens. */
572 sep = strrchr (pathname, '(');
573 if (sep == NULL)
574 {
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);
580 }
581 filename_len = sep - pathname;
582
192b62ce
TT
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));
4d1eb6b4 586
754c39c2
UW
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. */
797bc1cb
TT
590 gdb::unique_xmalloc_ptr<char> found_pathname
591 = solib_find (filename.c_str (), &found_file);
754c39c2
UW
592 if (found_pathname == NULL)
593 perror_with_name (pathname);
797bc1cb
TT
594 gdb_bfd_ref_ptr archive_bfd (solib_bfd_fopen (found_pathname.get (),
595 found_file));
4d1eb6b4
JB
596 if (archive_bfd == NULL)
597 {
598 warning (_("Could not open `%s' as an executable file: %s"),
192b62ce 599 filename.c_str (), bfd_errmsg (bfd_get_error ()));
4d1eb6b4
JB
600 return NULL;
601 }
602
192b62ce
TT
603 if (bfd_check_format (archive_bfd.get (), bfd_object))
604 return archive_bfd;
4d1eb6b4 605
192b62ce 606 if (! bfd_check_format (archive_bfd.get (), bfd_archive))
4d1eb6b4
JB
607 {
608 warning (_("\"%s\": not in executable format: %s."),
192b62ce 609 filename.c_str (), bfd_errmsg (bfd_get_error ()));
4d1eb6b4
JB
610 return NULL;
611 }
612
192b62ce
TT
613 gdb_bfd_ref_ptr object_bfd
614 (gdb_bfd_openr_next_archived_file (archive_bfd.get (), NULL));
4d1eb6b4
JB
615 while (object_bfd != NULL)
616 {
c7e97679 617 if (member_name == bfd_get_filename (object_bfd.get ()))
4d1eb6b4
JB
618 break;
619
192b62ce
TT
620 object_bfd = gdb_bfd_openr_next_archived_file (archive_bfd.get (),
621 object_bfd.get ());
4d1eb6b4
JB
622 }
623
624 if (object_bfd == NULL)
625 {
192b62ce
TT
626 warning (_("\"%s\": member \"%s\" missing."), filename.c_str (),
627 member_name.c_str ());
4d1eb6b4
JB
628 return NULL;
629 }
630
192b62ce 631 if (! bfd_check_format (object_bfd.get (), bfd_object))
4d1eb6b4
JB
632 {
633 warning (_("%s(%s): not in object format: %s."),
192b62ce
TT
634 filename.c_str (), member_name.c_str (),
635 bfd_errmsg (bfd_get_error ()));
4d1eb6b4
JB
636 return NULL;
637 }
638
754c39c2
UW
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. */
7b958a48
AM
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 ());
b030cf11 647
4d1eb6b4
JB
648 return object_bfd;
649}
650
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? */
654
655static struct obj_section *
656data_obj_section_from_objfile (struct objfile *objfile)
657{
658 struct obj_section *osect;
659
660 ALL_OBJFILE_OSECTIONS (objfile, osect)
fd361982 661 if (strcmp (bfd_section_name (osect->the_bfd_section), ".data") == 0)
4d1eb6b4
JB
662 return osect;
663
664 return NULL;
665}
666
667/* Return the TOC value corresponding to the given PC address,
668 or raise an error if the value could not be determined. */
669
670CORE_ADDR
671solib_aix_get_toc_value (CORE_ADDR pc)
672{
673 struct obj_section *pc_osect = find_pc_section (pc);
674 struct obj_section *data_osect;
675 CORE_ADDR result;
676
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));
681
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)"),
4262abfb 686 core_addr_to_string (pc), objfile_name (pc_osect->objfile));
4d1eb6b4
JB
687
688 result = (obj_section_addr (data_osect)
689 + xcoff_get_toc_offset (pc_osect->objfile));
eef401dc
SM
690
691 solib_aix_debug_printf ("pc=%s -> %s", core_addr_to_string (pc),
692 core_addr_to_string (result));
4d1eb6b4
JB
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
c90e7d63
SM
740 gdb::observers::normal_stop.attach (solib_aix_normal_stop_observer,
741 "solib-aix");
4d1eb6b4
JB
742
743 /* Debug this file's internals. */
744 add_setshow_boolean_cmd ("aix-solib", class_maintenance,
745 &solib_aix_debug, _("\
746Control the debugging traces for the solib-aix module."), _("\
747Show whether solib-aix debugging traces are enabled."), _("\
748When on, solib-aix debugging traces are enabled."),
dda83cd7
SM
749 NULL,
750 show_solib_aix_debug,
751 &setdebuglist, &showdebuglist);
4d1eb6b4 752}
This page took 0.979925 seconds and 4 git commands to generate.