Change build_address_symbolic to return std::string
[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"
76727919 27#include "observable.h"
4d1eb6b4
JB
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,
4d0fdd9b 137 std::vector<gdb_xml_value> &attributes)
4d1eb6b4 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");
4d0fdd9b 144 item->filename = xstrdup ((const char *) attr->value.get ());
4d1eb6b4
JB
145
146 attr = xml_find_attribute (attributes, "member");
147 if (attr != NULL)
4d0fdd9b 148 item->member_name = xstrdup ((const char *) attr->value.get ());
4d1eb6b4
JB
149
150 attr = xml_find_attribute (attributes, "text_addr");
4d0fdd9b 151 item->text_addr = * (ULONGEST *) attr->value.get ();
4d1eb6b4
JB
152
153 attr = xml_find_attribute (attributes, "text_size");
4d0fdd9b 154 item->text_size = * (ULONGEST *) attr->value.get ();
4d1eb6b4
JB
155
156 attr = xml_find_attribute (attributes, "data_addr");
4d0fdd9b 157 item->data_addr = * (ULONGEST *) attr->value.get ();
4d1eb6b4
JB
158
159 attr = xml_find_attribute (attributes, "data_size");
4d0fdd9b 160 item->data_size = * (ULONGEST *) attr->value.get ();
4d1eb6b4 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,
4d0fdd9b
SM
170 void *user_data,
171 std::vector<gdb_xml_value> &attributes)
4d1eb6b4 172{
4d0fdd9b
SM
173 char *version
174 = (char *) xml_find_attribute (attributes, "version")->value.get ();
4d1eb6b4
JB
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
184static void
185solib_aix_free_library_list (void *p)
186{
d0e449a1
SM
187 VEC (lm_info_aix_p) **result = (VEC (lm_info_aix_p) **) p;
188 lm_info_aix *info;
4d1eb6b4
JB
189 int ix;
190
191 if (solib_aix_debug)
192 fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_library_list\n");
193
d0e449a1 194 for (ix = 0; VEC_iterate (lm_info_aix_p, *result, ix, info); ix++)
6c401f72
SM
195 delete info;
196
d0e449a1 197 VEC_free (lm_info_aix_p, *result);
4d1eb6b4
JB
198 *result = NULL;
199}
200
201/* The allowed elements and attributes for an AIX library list
8c56e112 202 described in XML format. The root element is a <library-list-aix>. */
4d1eb6b4
JB
203
204static 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
215static 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
223static 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
229static const struct gdb_xml_element library_list_elements[] =
230{
8c56e112 231 { "library-list-aix", library_list_attributes, library_list_children,
4d1eb6b4
JB
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,
d0e449a1 237 and return an lm_info_aix_p vector.
4d1eb6b4
JB
238
239 Return NULL if the parsing failed. */
240
d0e449a1 241static VEC (lm_info_aix_p) *
4d1eb6b4
JB
242solib_aix_parse_libraries (const char *library)
243{
d0e449a1 244 VEC (lm_info_aix_p) *result = NULL;
4d1eb6b4
JB
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
d0e449a1 272static VEC (lm_info_aix_p) *
4d1eb6b4
JB
273solib_aix_get_library_list (struct inferior *inf, const char *warning_msg)
274{
275 struct solib_aix_inferior_data *data;
4d1eb6b4
JB
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
9018be22 282 gdb::optional<gdb::char_vector> library_document
f6ac5f3d 283 = target_read_stralloc (target_stack, TARGET_OBJECT_LIBRARIES_AIX,
b7b030ad 284 NULL);
9018be22 285 if (!library_document && warning_msg != NULL)
4d1eb6b4 286 {
ff99b71b 287 warning (_("%s (failed to read TARGET_OBJECT_LIBRARIES_AIX)"),
4d1eb6b4
JB
288 warning_msg);
289 return NULL;
290 }
4d1eb6b4
JB
291
292 if (solib_aix_debug)
293 fprintf_unfiltered (gdb_stdlog,
ff99b71b 294 "DEBUG: TARGET_OBJECT_LIBRARIES_AIX = \n%s\n",
9018be22 295 library_document->data ());
4d1eb6b4 296
9018be22 297 data->library_list = solib_aix_parse_libraries (library_document->data ());
4d1eb6b4
JB
298 if (data->library_list == NULL && warning_msg != NULL)
299 {
300 warning (_("%s (missing XML support?)"), warning_msg);
4d1eb6b4
JB
301 return NULL;
302 }
303
4d1eb6b4
JB
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
331static CORE_ADDR
332solib_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
363static void
364solib_aix_relocate_section_addresses (struct so_list *so,
365 struct target_section *sec)
366{
4d1eb6b4 367 struct bfd_section *bfd_sect = sec->the_bfd_section;
57e6060e 368 bfd *abfd = bfd_sect->owner;
4d1eb6b4 369 const char *section_name = bfd_section_name (abfd, bfd_sect);
d0e449a1 370 lm_info_aix *info = (lm_info_aix *) so->lm_info;
4d1eb6b4
JB
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 {
060cfbef
JB
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;
4d1eb6b4
JB
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. */
4d1eb6b4
JB
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
416static void
417solib_aix_free_so (struct so_list *so)
418{
6c401f72
SM
419 lm_info_aix *li = (lm_info_aix *) so->lm_info;
420
4d1eb6b4
JB
421 if (solib_aix_debug)
422 fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_so (%s)\n",
423 so->so_name);
6c401f72
SM
424
425 delete li;
4d1eb6b4
JB
426}
427
428/* Implement the "clear_solib" target_so_ops method. */
429
430static void
431solib_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
442static struct section_offsets *
443solib_aix_get_section_offsets (struct objfile *objfile,
d0e449a1 444 lm_info_aix *info)
4d1eb6b4
JB
445{
446 struct section_offsets *offsets;
447 bfd *abfd = objfile->obfd;
4d1eb6b4 448
fc270c35 449 offsets = XCNEWVEC (struct section_offsets, objfile->num_sections);
4d1eb6b4
JB
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
494static void
495solib_aix_solib_create_inferior_hook (int from_tty)
496{
497 const char *warning_msg = "unable to relocate main executable";
d0e449a1
SM
498 VEC (lm_info_aix_p) *library_list;
499 lm_info_aix *exec_info;
4d1eb6b4
JB
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
d0e449a1 508 if (VEC_length (lm_info_aix_p, library_list) < 1)
4d1eb6b4
JB
509 {
510 warning (_("unable to relocate main executable (no info from loader)"));
511 return;
512 }
513
d0e449a1 514 exec_info = VEC_index (lm_info_aix_p, library_list, 0);
4d1eb6b4
JB
515
516 if (symfile_objfile != NULL)
517 {
518 struct section_offsets *offsets
519 = solib_aix_get_section_offsets (symfile_objfile, exec_info);
520 struct cleanup *cleanup = make_cleanup (xfree, offsets);
521
522 objfile_relocate (symfile_objfile, offsets);
523 do_cleanups (cleanup);
524 }
525}
526
4d1eb6b4
JB
527/* Implement the "current_sos" target_so_ops method. */
528
529static struct so_list *
530solib_aix_current_sos (void)
531{
532 struct so_list *start = NULL, *last = NULL;
d0e449a1
SM
533 VEC (lm_info_aix_p) *library_list;
534 lm_info_aix *info;
4d1eb6b4
JB
535 int ix;
536
537 library_list = solib_aix_get_library_list (current_inferior (), NULL);
538 if (library_list == NULL)
539 return NULL;
540
541 /* Build a struct so_list for each entry on the list.
542 We skip the first entry, since this is the entry corresponding
543 to the main executable, not a shared library. */
d0e449a1 544 for (ix = 1; VEC_iterate (lm_info_aix_p, library_list, ix, info); ix++)
4d1eb6b4 545 {
41bf6aca 546 struct so_list *new_solib = XCNEW (struct so_list);
6c401f72 547 std::string so_name;
4d1eb6b4 548
6c401f72 549 if (info->member_name.empty ())
4d1eb6b4
JB
550 {
551 /* INFO->FILENAME is probably not an archive, but rather
552 a shared object. Unusual, but it should be possible
553 to link a program against a shared object directory,
554 without having to put it in an archive first. */
6c401f72 555 so_name = info->filename;
4d1eb6b4
JB
556 }
557 else
558 {
559 /* This is the usual case on AIX, where the shared object
560 is a member of an archive. Create a synthetic so_name
561 that follows the same convention as AIX's ldd tool
562 (Eg: "/lib/libc.a(shr.o)"). */
6c401f72
SM
563 so_name = string_printf ("%s(%s)", info->filename.c_str (),
564 info->member_name.c_str ());
4d1eb6b4 565 }
6c401f72 566 strncpy (new_solib->so_original_name, so_name.c_str (),
4d1eb6b4
JB
567 SO_NAME_MAX_PATH_SIZE - 1);
568 new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
569 memcpy (new_solib->so_name, new_solib->so_original_name,
570 SO_NAME_MAX_PATH_SIZE);
6c401f72 571 new_solib->lm_info = new lm_info_aix (*info);
4d1eb6b4
JB
572
573 /* Add it to the list. */
574 if (!start)
575 last = start = new_solib;
576 else
577 {
578 last->next = new_solib;
579 last = new_solib;
580 }
581 }
582
583 return start;
584}
585
586/* Implement the "open_symbol_file_object" target_so_ops method. */
587
588static int
bf469271 589solib_aix_open_symbol_file_object (int from_tty)
4d1eb6b4
JB
590{
591 return 0;
592}
593
594/* Implement the "in_dynsym_resolve_code" target_so_ops method. */
595
596static int
597solib_aix_in_dynsym_resolve_code (CORE_ADDR pc)
598{
599 return 0;
600}
601
602/* Implement the "bfd_open" target_so_ops method. */
603
192b62ce 604static gdb_bfd_ref_ptr
692d6f97 605solib_aix_bfd_open (const char *pathname)
4d1eb6b4
JB
606{
607 /* The pathname is actually a synthetic filename with the following
608 form: "/path/to/sharedlib(member.o)" (double-quotes excluded).
609 split this into archive name and member name.
610
611 FIXME: This is a little hacky. Perhaps we should provide access
612 to the solib's lm_info here? */
613 const int path_len = strlen (pathname);
692d6f97 614 const char *sep;
4d1eb6b4 615 int filename_len;
754c39c2 616 int found_file;
4d1eb6b4
JB
617
618 if (pathname[path_len - 1] != ')')
619 return solib_bfd_open (pathname);
620
621 /* Search for the associated parens. */
622 sep = strrchr (pathname, '(');
623 if (sep == NULL)
624 {
625 /* Should never happen, but recover as best as we can (trying
626 to open pathname without decoding, possibly leading to
627 a failure), rather than triggering an assert failure). */
628 warning (_("missing '(' in shared object pathname: %s"), pathname);
629 return solib_bfd_open (pathname);
630 }
631 filename_len = sep - pathname;
632
192b62ce
TT
633 std::string filename (string_printf ("%.*s", filename_len, pathname));
634 std::string member_name (string_printf ("%.*s", path_len - filename_len - 2,
635 sep + 1));
4d1eb6b4 636
754c39c2
UW
637 /* Calling solib_find makes certain that sysroot path is set properly
638 if program has a dependency on .a archive and sysroot is set via
639 set sysroot command. */
797bc1cb
TT
640 gdb::unique_xmalloc_ptr<char> found_pathname
641 = solib_find (filename.c_str (), &found_file);
754c39c2
UW
642 if (found_pathname == NULL)
643 perror_with_name (pathname);
797bc1cb
TT
644 gdb_bfd_ref_ptr archive_bfd (solib_bfd_fopen (found_pathname.get (),
645 found_file));
4d1eb6b4
JB
646 if (archive_bfd == NULL)
647 {
648 warning (_("Could not open `%s' as an executable file: %s"),
192b62ce 649 filename.c_str (), bfd_errmsg (bfd_get_error ()));
4d1eb6b4
JB
650 return NULL;
651 }
652
192b62ce
TT
653 if (bfd_check_format (archive_bfd.get (), bfd_object))
654 return archive_bfd;
4d1eb6b4 655
192b62ce 656 if (! bfd_check_format (archive_bfd.get (), bfd_archive))
4d1eb6b4
JB
657 {
658 warning (_("\"%s\": not in executable format: %s."),
192b62ce 659 filename.c_str (), bfd_errmsg (bfd_get_error ()));
4d1eb6b4
JB
660 return NULL;
661 }
662
192b62ce
TT
663 gdb_bfd_ref_ptr object_bfd
664 (gdb_bfd_openr_next_archived_file (archive_bfd.get (), NULL));
4d1eb6b4
JB
665 while (object_bfd != NULL)
666 {
192b62ce 667 if (member_name == object_bfd->filename)
4d1eb6b4
JB
668 break;
669
192b62ce
TT
670 object_bfd = gdb_bfd_openr_next_archived_file (archive_bfd.get (),
671 object_bfd.get ());
4d1eb6b4
JB
672 }
673
674 if (object_bfd == NULL)
675 {
192b62ce
TT
676 warning (_("\"%s\": member \"%s\" missing."), filename.c_str (),
677 member_name.c_str ());
4d1eb6b4
JB
678 return NULL;
679 }
680
192b62ce 681 if (! bfd_check_format (object_bfd.get (), bfd_object))
4d1eb6b4
JB
682 {
683 warning (_("%s(%s): not in object format: %s."),
192b62ce
TT
684 filename.c_str (), member_name.c_str (),
685 bfd_errmsg (bfd_get_error ()));
4d1eb6b4
JB
686 return NULL;
687 }
688
754c39c2
UW
689 /* Override the returned bfd's name with the name returned from solib_find
690 along with appended parenthesized member name in order to allow commands
691 listing all shared libraries to display. Otherwise, we would only be
692 displaying the name of the archive member object. */
192b62ce 693 xfree (bfd_get_filename (object_bfd.get ()));
754c39c2 694 object_bfd->filename = xstrprintf ("%s%s",
192b62ce
TT
695 bfd_get_filename (archive_bfd.get ()),
696 sep);
b030cf11 697
4d1eb6b4
JB
698 return object_bfd;
699}
700
701/* Return the obj_section corresponding to OBJFILE's data section,
702 or NULL if not found. */
703/* FIXME: Define in a more general location? */
704
705static struct obj_section *
706data_obj_section_from_objfile (struct objfile *objfile)
707{
708 struct obj_section *osect;
709
710 ALL_OBJFILE_OSECTIONS (objfile, osect)
711 if (strcmp (bfd_section_name (objfile->obfd, osect->the_bfd_section),
712 ".data") == 0)
713 return osect;
714
715 return NULL;
716}
717
718/* Return the TOC value corresponding to the given PC address,
719 or raise an error if the value could not be determined. */
720
721CORE_ADDR
722solib_aix_get_toc_value (CORE_ADDR pc)
723{
724 struct obj_section *pc_osect = find_pc_section (pc);
725 struct obj_section *data_osect;
726 CORE_ADDR result;
727
728 if (pc_osect == NULL)
729 error (_("unable to find TOC entry for pc %s "
730 "(no section contains this PC)"),
731 core_addr_to_string (pc));
732
733 data_osect = data_obj_section_from_objfile (pc_osect->objfile);
734 if (data_osect == NULL)
735 error (_("unable to find TOC entry for pc %s "
736 "(%s has no data section)"),
4262abfb 737 core_addr_to_string (pc), objfile_name (pc_osect->objfile));
4d1eb6b4
JB
738
739 result = (obj_section_addr (data_osect)
740 + xcoff_get_toc_offset (pc_osect->objfile));
741 if (solib_aix_debug)
742 fprintf_unfiltered (gdb_stdlog,
743 "DEBUG: solib_aix_get_toc_value (pc=%s) -> %s\n",
744 core_addr_to_string (pc),
745 core_addr_to_string (result));
746
747 return result;
748}
749
750/* This module's normal_stop observer. */
751
752static void
753solib_aix_normal_stop_observer (struct bpstats *unused_1, int unused_2)
754{
755 struct solib_aix_inferior_data *data
756 = get_solib_aix_inferior_data (current_inferior ());
757
758 /* The inferior execution has been resumed, and it just stopped
759 again. This means that the list of shared libraries may have
760 evolved. Reset our cached value. */
761 solib_aix_free_library_list (&data->library_list);
762}
763
764/* Implements the "show debug aix-solib" command. */
765
766static void
767show_solib_aix_debug (struct ui_file *file, int from_tty,
768 struct cmd_list_element *c, const char *value)
769{
770 fprintf_filtered (file, _("solib-aix debugging is %s.\n"), value);
771}
772
773/* The target_so_ops for AIX targets. */
774struct target_so_ops solib_aix_so_ops;
775
4d1eb6b4
JB
776void
777_initialize_solib_aix (void)
778{
779 solib_aix_so_ops.relocate_section_addresses
780 = solib_aix_relocate_section_addresses;
781 solib_aix_so_ops.free_so = solib_aix_free_so;
782 solib_aix_so_ops.clear_solib = solib_aix_clear_solib;
783 solib_aix_so_ops.solib_create_inferior_hook
784 = solib_aix_solib_create_inferior_hook;
4d1eb6b4
JB
785 solib_aix_so_ops.current_sos = solib_aix_current_sos;
786 solib_aix_so_ops.open_symbol_file_object
787 = solib_aix_open_symbol_file_object;
788 solib_aix_so_ops.in_dynsym_resolve_code
789 = solib_aix_in_dynsym_resolve_code;
790 solib_aix_so_ops.bfd_open = solib_aix_bfd_open;
791
792 solib_aix_inferior_data_handle = register_inferior_data ();
793
76727919 794 gdb::observers::normal_stop.attach (solib_aix_normal_stop_observer);
4d1eb6b4
JB
795
796 /* Debug this file's internals. */
797 add_setshow_boolean_cmd ("aix-solib", class_maintenance,
798 &solib_aix_debug, _("\
799Control the debugging traces for the solib-aix module."), _("\
800Show whether solib-aix debugging traces are enabled."), _("\
801When on, solib-aix debugging traces are enabled."),
802 NULL,
803 show_solib_aix_debug,
804 &setdebuglist, &showdebuglist);
805}
This page took 0.6526 seconds and 4 git commands to generate.