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