cris: Check UNDEFWEAK_NO_DYNAMIC_RELOC
[deliverable/binutils-gdb.git] / gdb / solib-aix.c
CommitLineData
61baf725 1/* Copyright (C) 2013-2017 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;
274 char *library_document;
275 struct cleanup *cleanup;
276
277 /* If already computed, return the cached value. */
278 data = get_solib_aix_inferior_data (inf);
279 if (data->library_list != NULL)
280 return data->library_list;
281
282 library_document = target_read_stralloc (&current_target,
ff99b71b 283 TARGET_OBJECT_LIBRARIES_AIX,
4d1eb6b4
JB
284 NULL);
285 if (library_document == NULL && warning_msg != NULL)
286 {
ff99b71b 287 warning (_("%s (failed to read TARGET_OBJECT_LIBRARIES_AIX)"),
4d1eb6b4
JB
288 warning_msg);
289 return NULL;
290 }
291 cleanup = make_cleanup (xfree, library_document);
292
293 if (solib_aix_debug)
294 fprintf_unfiltered (gdb_stdlog,
ff99b71b 295 "DEBUG: TARGET_OBJECT_LIBRARIES_AIX = \n%s\n",
4d1eb6b4
JB
296 library_document);
297
298 data->library_list = solib_aix_parse_libraries (library_document);
299 if (data->library_list == NULL && warning_msg != NULL)
300 {
301 warning (_("%s (missing XML support?)"), warning_msg);
302 do_cleanups (cleanup);
303 return NULL;
304 }
305
306 do_cleanups (cleanup);
307 return data->library_list;
308}
309
310/* If the .bss section's VMA is set to an address located before
311 the end of the .data section, causing the two sections to overlap,
312 return the overlap in bytes. Otherwise, return zero.
313
314 Motivation:
315
316 The GNU linker sometimes sets the start address of the .bss session
317 before the end of the .data section, making the 2 sections overlap.
318 The loader appears to handle this situation gracefully, by simply
319 loading the bss section right after the end of the .data section.
320
321 This means that the .data and the .bss sections are sometimes
322 no longer relocated by the same amount. The problem is that
323 the ldinfo data does not contain any information regarding
324 the relocation of the .bss section, assuming that it would be
325 identical to the information provided for the .data section
326 (this is what would normally happen if the program was linked
327 correctly).
328
329 GDB therefore needs to detect those cases, and make the corresponding
330 adjustment to the .bss section offset computed from the ldinfo data
331 when necessary. This function returns the adjustment amount (or
332 zero when no adjustment is needed). */
333
334static CORE_ADDR
335solib_aix_bss_data_overlap (bfd *abfd)
336{
337 struct bfd_section *data_sect, *bss_sect;
338
339 data_sect = bfd_get_section_by_name (abfd, ".data");
340 if (data_sect == NULL)
341 return 0; /* No overlap possible. */
342
343 bss_sect = bfd_get_section_by_name (abfd, ".bss");
344 if (bss_sect == NULL)
345 return 0; /* No overlap possible. */
346
347 /* Assume the problem only occurs with linkers that place the .bss
348 section after the .data section (the problem has only been
349 observed when using the GNU linker, and the default linker
350 script always places the .data and .bss sections in that order). */
351 if (bfd_section_vma (abfd, bss_sect)
352 < bfd_section_vma (abfd, data_sect))
353 return 0;
354
355 if (bfd_section_vma (abfd, bss_sect)
356 < bfd_section_vma (abfd, data_sect) + bfd_get_section_size (data_sect))
357 return ((bfd_section_vma (abfd, data_sect)
358 + bfd_get_section_size (data_sect))
359 - bfd_section_vma (abfd, bss_sect));
360
361 return 0;
362}
363
364/* Implement the "relocate_section_addresses" target_so_ops method. */
365
366static void
367solib_aix_relocate_section_addresses (struct so_list *so,
368 struct target_section *sec)
369{
4d1eb6b4 370 struct bfd_section *bfd_sect = sec->the_bfd_section;
57e6060e 371 bfd *abfd = bfd_sect->owner;
4d1eb6b4 372 const char *section_name = bfd_section_name (abfd, bfd_sect);
d0e449a1 373 lm_info_aix *info = (lm_info_aix *) so->lm_info;
4d1eb6b4
JB
374
375 if (strcmp (section_name, ".text") == 0)
376 {
377 sec->addr = info->text_addr;
378 sec->endaddr = sec->addr + info->text_size;
379
380 /* The text address given to us by the loader contains
381 XCOFF headers, so we need to adjust by this much. */
382 sec->addr += bfd_sect->filepos;
383 }
384 else if (strcmp (section_name, ".data") == 0)
385 {
386 sec->addr = info->data_addr;
387 sec->endaddr = sec->addr + info->data_size;
388 }
389 else if (strcmp (section_name, ".bss") == 0)
390 {
060cfbef
JB
391 /* The information provided by the loader does not include
392 the address of the .bss section, but we know that it gets
393 relocated by the same offset as the .data section. So,
394 compute the relocation offset for the .data section, and
395 apply it to the .bss section as well. If the .data section
396 is not defined (which seems highly unlikely), do our best
397 by assuming no relocation. */
398 struct bfd_section *data_sect
399 = bfd_get_section_by_name (abfd, ".data");
400 CORE_ADDR data_offset = 0;
401
402 if (data_sect != NULL)
403 data_offset = info->data_addr - bfd_section_vma (abfd, data_sect);
404
405 sec->addr = bfd_section_vma (abfd, bfd_sect) + data_offset;
4d1eb6b4
JB
406 sec->addr += solib_aix_bss_data_overlap (abfd);
407 sec->endaddr = sec->addr + bfd_section_size (abfd, bfd_sect);
408 }
409 else
410 {
411 /* All other sections should not be relocated. */
4d1eb6b4
JB
412 sec->addr = bfd_section_vma (abfd, bfd_sect);
413 sec->endaddr = sec->addr + bfd_section_size (abfd, bfd_sect);
414 }
415}
416
417/* Implement the "free_so" target_so_ops method. */
418
419static void
420solib_aix_free_so (struct so_list *so)
421{
6c401f72
SM
422 lm_info_aix *li = (lm_info_aix *) so->lm_info;
423
4d1eb6b4
JB
424 if (solib_aix_debug)
425 fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_so (%s)\n",
426 so->so_name);
6c401f72
SM
427
428 delete li;
4d1eb6b4
JB
429}
430
431/* Implement the "clear_solib" target_so_ops method. */
432
433static void
434solib_aix_clear_solib (void)
435{
436 /* Nothing needed. */
437}
438
439/* Compute and return the OBJFILE's section_offset array, using
440 the associated loader info (INFO).
441
442 The resulting array is computed on the heap and must be
443 deallocated after use. */
444
445static struct section_offsets *
446solib_aix_get_section_offsets (struct objfile *objfile,
d0e449a1 447 lm_info_aix *info)
4d1eb6b4
JB
448{
449 struct section_offsets *offsets;
450 bfd *abfd = objfile->obfd;
4d1eb6b4 451
fc270c35 452 offsets = XCNEWVEC (struct section_offsets, objfile->num_sections);
4d1eb6b4
JB
453
454 /* .text */
455
456 if (objfile->sect_index_text != -1)
457 {
458 struct bfd_section *sect
459 = objfile->sections[objfile->sect_index_text].the_bfd_section;
460
461 offsets->offsets[objfile->sect_index_text]
462 = info->text_addr + sect->filepos - bfd_section_vma (abfd, sect);
463 }
464
465 /* .data */
466
467 if (objfile->sect_index_data != -1)
468 {
469 struct bfd_section *sect
470 = objfile->sections[objfile->sect_index_data].the_bfd_section;
471
472 offsets->offsets[objfile->sect_index_data]
473 = info->data_addr - bfd_section_vma (abfd, sect);
474 }
475
476 /* .bss
477
478 The offset of the .bss section should be identical to the offset
479 of the .data section. If no .data section (which seems hard to
480 believe it is possible), assume it is zero. */
481
482 if (objfile->sect_index_bss != -1
483 && objfile->sect_index_data != -1)
484 {
485 offsets->offsets[objfile->sect_index_bss]
486 = (offsets->offsets[objfile->sect_index_data]
487 + solib_aix_bss_data_overlap (abfd));
488 }
489
490 /* All other sections should not need relocation. */
491
492 return offsets;
493}
494
495/* Implement the "solib_create_inferior_hook" target_so_ops method. */
496
497static void
498solib_aix_solib_create_inferior_hook (int from_tty)
499{
500 const char *warning_msg = "unable to relocate main executable";
d0e449a1
SM
501 VEC (lm_info_aix_p) *library_list;
502 lm_info_aix *exec_info;
4d1eb6b4
JB
503
504 /* We need to relocate the main executable... */
505
506 library_list = solib_aix_get_library_list (current_inferior (),
507 warning_msg);
508 if (library_list == NULL)
509 return; /* Warning already printed. */
510
d0e449a1 511 if (VEC_length (lm_info_aix_p, library_list) < 1)
4d1eb6b4
JB
512 {
513 warning (_("unable to relocate main executable (no info from loader)"));
514 return;
515 }
516
d0e449a1 517 exec_info = VEC_index (lm_info_aix_p, library_list, 0);
4d1eb6b4
JB
518
519 if (symfile_objfile != NULL)
520 {
521 struct section_offsets *offsets
522 = solib_aix_get_section_offsets (symfile_objfile, exec_info);
523 struct cleanup *cleanup = make_cleanup (xfree, offsets);
524
525 objfile_relocate (symfile_objfile, offsets);
526 do_cleanups (cleanup);
527 }
528}
529
4d1eb6b4
JB
530/* Implement the "current_sos" target_so_ops method. */
531
532static struct so_list *
533solib_aix_current_sos (void)
534{
535 struct so_list *start = NULL, *last = NULL;
d0e449a1
SM
536 VEC (lm_info_aix_p) *library_list;
537 lm_info_aix *info;
4d1eb6b4
JB
538 int ix;
539
540 library_list = solib_aix_get_library_list (current_inferior (), NULL);
541 if (library_list == NULL)
542 return NULL;
543
544 /* Build a struct so_list for each entry on the list.
545 We skip the first entry, since this is the entry corresponding
546 to the main executable, not a shared library. */
d0e449a1 547 for (ix = 1; VEC_iterate (lm_info_aix_p, library_list, ix, info); ix++)
4d1eb6b4 548 {
41bf6aca 549 struct so_list *new_solib = XCNEW (struct so_list);
6c401f72 550 std::string so_name;
4d1eb6b4 551
6c401f72 552 if (info->member_name.empty ())
4d1eb6b4
JB
553 {
554 /* INFO->FILENAME is probably not an archive, but rather
555 a shared object. Unusual, but it should be possible
556 to link a program against a shared object directory,
557 without having to put it in an archive first. */
6c401f72 558 so_name = info->filename;
4d1eb6b4
JB
559 }
560 else
561 {
562 /* This is the usual case on AIX, where the shared object
563 is a member of an archive. Create a synthetic so_name
564 that follows the same convention as AIX's ldd tool
565 (Eg: "/lib/libc.a(shr.o)"). */
6c401f72
SM
566 so_name = string_printf ("%s(%s)", info->filename.c_str (),
567 info->member_name.c_str ());
4d1eb6b4 568 }
6c401f72 569 strncpy (new_solib->so_original_name, so_name.c_str (),
4d1eb6b4
JB
570 SO_NAME_MAX_PATH_SIZE - 1);
571 new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
572 memcpy (new_solib->so_name, new_solib->so_original_name,
573 SO_NAME_MAX_PATH_SIZE);
6c401f72 574 new_solib->lm_info = new lm_info_aix (*info);
4d1eb6b4
JB
575
576 /* Add it to the list. */
577 if (!start)
578 last = start = new_solib;
579 else
580 {
581 last->next = new_solib;
582 last = new_solib;
583 }
584 }
585
586 return start;
587}
588
589/* Implement the "open_symbol_file_object" target_so_ops method. */
590
591static int
bf469271 592solib_aix_open_symbol_file_object (int from_tty)
4d1eb6b4
JB
593{
594 return 0;
595}
596
597/* Implement the "in_dynsym_resolve_code" target_so_ops method. */
598
599static int
600solib_aix_in_dynsym_resolve_code (CORE_ADDR pc)
601{
602 return 0;
603}
604
605/* Implement the "bfd_open" target_so_ops method. */
606
192b62ce 607static gdb_bfd_ref_ptr
4d1eb6b4
JB
608solib_aix_bfd_open (char *pathname)
609{
610 /* The pathname is actually a synthetic filename with the following
611 form: "/path/to/sharedlib(member.o)" (double-quotes excluded).
612 split this into archive name and member name.
613
614 FIXME: This is a little hacky. Perhaps we should provide access
615 to the solib's lm_info here? */
616 const int path_len = strlen (pathname);
617 char *sep;
4d1eb6b4 618 int filename_len;
754c39c2
UW
619 int found_file;
620 char *found_pathname;
4d1eb6b4
JB
621
622 if (pathname[path_len - 1] != ')')
623 return solib_bfd_open (pathname);
624
625 /* Search for the associated parens. */
626 sep = strrchr (pathname, '(');
627 if (sep == NULL)
628 {
629 /* Should never happen, but recover as best as we can (trying
630 to open pathname without decoding, possibly leading to
631 a failure), rather than triggering an assert failure). */
632 warning (_("missing '(' in shared object pathname: %s"), pathname);
633 return solib_bfd_open (pathname);
634 }
635 filename_len = sep - pathname;
636
192b62ce
TT
637 std::string filename (string_printf ("%.*s", filename_len, pathname));
638 std::string member_name (string_printf ("%.*s", path_len - filename_len - 2,
639 sep + 1));
4d1eb6b4 640
754c39c2
UW
641 /* Calling solib_find makes certain that sysroot path is set properly
642 if program has a dependency on .a archive and sysroot is set via
643 set sysroot command. */
192b62ce 644 found_pathname = solib_find (filename.c_str (), &found_file);
754c39c2
UW
645 if (found_pathname == NULL)
646 perror_with_name (pathname);
192b62ce 647 gdb_bfd_ref_ptr archive_bfd (solib_bfd_fopen (found_pathname, found_file));
4d1eb6b4
JB
648 if (archive_bfd == NULL)
649 {
650 warning (_("Could not open `%s' as an executable file: %s"),
192b62ce 651 filename.c_str (), bfd_errmsg (bfd_get_error ()));
4d1eb6b4
JB
652 return NULL;
653 }
654
192b62ce
TT
655 if (bfd_check_format (archive_bfd.get (), bfd_object))
656 return archive_bfd;
4d1eb6b4 657
192b62ce 658 if (! bfd_check_format (archive_bfd.get (), bfd_archive))
4d1eb6b4
JB
659 {
660 warning (_("\"%s\": not in executable format: %s."),
192b62ce 661 filename.c_str (), bfd_errmsg (bfd_get_error ()));
4d1eb6b4
JB
662 return NULL;
663 }
664
192b62ce
TT
665 gdb_bfd_ref_ptr object_bfd
666 (gdb_bfd_openr_next_archived_file (archive_bfd.get (), NULL));
4d1eb6b4
JB
667 while (object_bfd != NULL)
668 {
192b62ce 669 if (member_name == object_bfd->filename)
4d1eb6b4
JB
670 break;
671
192b62ce
TT
672 object_bfd = gdb_bfd_openr_next_archived_file (archive_bfd.get (),
673 object_bfd.get ());
4d1eb6b4
JB
674 }
675
676 if (object_bfd == NULL)
677 {
192b62ce
TT
678 warning (_("\"%s\": member \"%s\" missing."), filename.c_str (),
679 member_name.c_str ());
4d1eb6b4
JB
680 return NULL;
681 }
682
192b62ce 683 if (! bfd_check_format (object_bfd.get (), bfd_object))
4d1eb6b4
JB
684 {
685 warning (_("%s(%s): not in object format: %s."),
192b62ce
TT
686 filename.c_str (), member_name.c_str (),
687 bfd_errmsg (bfd_get_error ()));
4d1eb6b4
JB
688 return NULL;
689 }
690
754c39c2
UW
691 /* Override the returned bfd's name with the name returned from solib_find
692 along with appended parenthesized member name in order to allow commands
693 listing all shared libraries to display. Otherwise, we would only be
694 displaying the name of the archive member object. */
192b62ce 695 xfree (bfd_get_filename (object_bfd.get ()));
754c39c2 696 object_bfd->filename = xstrprintf ("%s%s",
192b62ce
TT
697 bfd_get_filename (archive_bfd.get ()),
698 sep);
b030cf11 699
4d1eb6b4
JB
700 return object_bfd;
701}
702
703/* Return the obj_section corresponding to OBJFILE's data section,
704 or NULL if not found. */
705/* FIXME: Define in a more general location? */
706
707static struct obj_section *
708data_obj_section_from_objfile (struct objfile *objfile)
709{
710 struct obj_section *osect;
711
712 ALL_OBJFILE_OSECTIONS (objfile, osect)
713 if (strcmp (bfd_section_name (objfile->obfd, osect->the_bfd_section),
714 ".data") == 0)
715 return osect;
716
717 return NULL;
718}
719
720/* Return the TOC value corresponding to the given PC address,
721 or raise an error if the value could not be determined. */
722
723CORE_ADDR
724solib_aix_get_toc_value (CORE_ADDR pc)
725{
726 struct obj_section *pc_osect = find_pc_section (pc);
727 struct obj_section *data_osect;
728 CORE_ADDR result;
729
730 if (pc_osect == NULL)
731 error (_("unable to find TOC entry for pc %s "
732 "(no section contains this PC)"),
733 core_addr_to_string (pc));
734
735 data_osect = data_obj_section_from_objfile (pc_osect->objfile);
736 if (data_osect == NULL)
737 error (_("unable to find TOC entry for pc %s "
738 "(%s has no data section)"),
4262abfb 739 core_addr_to_string (pc), objfile_name (pc_osect->objfile));
4d1eb6b4
JB
740
741 result = (obj_section_addr (data_osect)
742 + xcoff_get_toc_offset (pc_osect->objfile));
743 if (solib_aix_debug)
744 fprintf_unfiltered (gdb_stdlog,
745 "DEBUG: solib_aix_get_toc_value (pc=%s) -> %s\n",
746 core_addr_to_string (pc),
747 core_addr_to_string (result));
748
749 return result;
750}
751
752/* This module's normal_stop observer. */
753
754static void
755solib_aix_normal_stop_observer (struct bpstats *unused_1, int unused_2)
756{
757 struct solib_aix_inferior_data *data
758 = get_solib_aix_inferior_data (current_inferior ());
759
760 /* The inferior execution has been resumed, and it just stopped
761 again. This means that the list of shared libraries may have
762 evolved. Reset our cached value. */
763 solib_aix_free_library_list (&data->library_list);
764}
765
766/* Implements the "show debug aix-solib" command. */
767
768static void
769show_solib_aix_debug (struct ui_file *file, int from_tty,
770 struct cmd_list_element *c, const char *value)
771{
772 fprintf_filtered (file, _("solib-aix debugging is %s.\n"), value);
773}
774
775/* The target_so_ops for AIX targets. */
776struct target_so_ops solib_aix_so_ops;
777
4d1eb6b4
JB
778void
779_initialize_solib_aix (void)
780{
781 solib_aix_so_ops.relocate_section_addresses
782 = solib_aix_relocate_section_addresses;
783 solib_aix_so_ops.free_so = solib_aix_free_so;
784 solib_aix_so_ops.clear_solib = solib_aix_clear_solib;
785 solib_aix_so_ops.solib_create_inferior_hook
786 = solib_aix_solib_create_inferior_hook;
4d1eb6b4
JB
787 solib_aix_so_ops.current_sos = solib_aix_current_sos;
788 solib_aix_so_ops.open_symbol_file_object
789 = solib_aix_open_symbol_file_object;
790 solib_aix_so_ops.in_dynsym_resolve_code
791 = solib_aix_in_dynsym_resolve_code;
792 solib_aix_so_ops.bfd_open = solib_aix_bfd_open;
793
794 solib_aix_inferior_data_handle = register_inferior_data ();
795
796 observer_attach_normal_stop (solib_aix_normal_stop_observer);
797
798 /* Debug this file's internals. */
799 add_setshow_boolean_cmd ("aix-solib", class_maintenance,
800 &solib_aix_debug, _("\
801Control the debugging traces for the solib-aix module."), _("\
802Show whether solib-aix debugging traces are enabled."), _("\
803When on, solib-aix debugging traces are enabled."),
804 NULL,
805 show_solib_aix_debug,
806 &setdebuglist, &showdebuglist);
807}
This page took 0.500057 seconds and 4 git commands to generate.