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