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