Introduce complete_nested_command_line
[deliverable/binutils-gdb.git] / gdb / solib-aix.c
CommitLineData
42a4f53d 1/* Copyright (C) 2013-2019 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 28#include "gdbcmd.h"
72412762 29#include "common/scope-exit.h"
4d1eb6b4
JB
30
31/* Variable controlling the output of the debugging traces for
32 this module. */
33static int solib_aix_debug;
34
35/* Our private data in struct so_list. */
36
d0e449a1 37struct lm_info_aix : public lm_info_base
4d1eb6b4
JB
38{
39 /* The name of the file mapped by the loader. Apart from the entry
40 for the main executable, this is usually a shared library (which,
41 on AIX, is an archive library file, created using the "ar"
42 command). */
6c401f72 43 std::string filename;
4d1eb6b4
JB
44
45 /* The name of the shared object file with the actual dynamic
6c401f72
SM
46 loading dependency. This may be empty (Eg. main executable). */
47 std::string member_name;
4d1eb6b4
JB
48
49 /* The address in inferior memory where the text section got mapped. */
6c401f72 50 CORE_ADDR text_addr = 0;
4d1eb6b4
JB
51
52 /* The size of the text section, obtained via the loader data. */
6c401f72 53 ULONGEST text_size = 0;
4d1eb6b4
JB
54
55 /* The address in inferior memory where the data section got mapped. */
6c401f72 56 CORE_ADDR data_addr = 0;
4d1eb6b4
JB
57
58 /* The size of the data section, obtained via the loader data. */
6c401f72 59 ULONGEST data_size = 0;
4d1eb6b4
JB
60};
61
d0e449a1
SM
62typedef lm_info_aix *lm_info_aix_p;
63DEF_VEC_P(lm_info_aix_p);
4d1eb6b4 64
4d1eb6b4
JB
65/* This module's per-inferior data. */
66
67struct solib_aix_inferior_data
68{
69 /* The list of shared libraries. NULL if not computed yet.
70
71 Note that the first element of this list is always the main
72 executable, which is not technically a shared library. But
73 we need that information to perform its relocation, and
74 the same principles applied to shared libraries also apply
75 to the main executable. So it's simpler to keep it as part
76 of this list. */
d0e449a1 77 VEC (lm_info_aix_p) *library_list;
4d1eb6b4
JB
78};
79
80/* Key to our per-inferior data. */
81static const struct inferior_data *solib_aix_inferior_data_handle;
82
83/* Return this module's data for the given inferior.
84 If none is found, add a zero'ed one now. */
85
86static struct solib_aix_inferior_data *
87get_solib_aix_inferior_data (struct inferior *inf)
88{
89 struct solib_aix_inferior_data *data;
90
19ba03f4
SM
91 data = ((struct solib_aix_inferior_data *)
92 inferior_data (inf, solib_aix_inferior_data_handle));
4d1eb6b4
JB
93 if (data == NULL)
94 {
41bf6aca 95 data = XCNEW (struct solib_aix_inferior_data);
4d1eb6b4
JB
96 set_inferior_data (inf, solib_aix_inferior_data_handle, data);
97 }
98
99 return data;
100}
101
102#if !defined(HAVE_LIBEXPAT)
103
104/* Dummy implementation if XML support is not compiled in. */
105
d0e449a1 106static VEC (lm_info_aix_p) *
4d1eb6b4
JB
107solib_aix_parse_libraries (const char *library)
108{
109 static int have_warned;
110
111 if (!have_warned)
112 {
113 have_warned = 1;
114 warning (_("Can not parse XML library list; XML support was disabled "
115 "at compile time"));
116 }
117
118 return NULL;
119}
120
814a3ff7
JB
121/* Dummy implementation if XML support is not compiled in. */
122
123static void
124solib_aix_free_library_list (void *p)
125{
126}
127
4d1eb6b4
JB
128#else /* HAVE_LIBEXPAT */
129
130#include "xml-support.h"
131
132/* Handle the start of a <library> element. */
133
134static void
135library_list_start_library (struct gdb_xml_parser *parser,
136 const struct gdb_xml_element *element,
137 void *user_data,
4d0fdd9b 138 std::vector<gdb_xml_value> &attributes)
4d1eb6b4 139{
d0e449a1 140 VEC (lm_info_aix_p) **list = (VEC (lm_info_aix_p) **) user_data;
6c401f72 141 lm_info_aix *item = new lm_info_aix;
4d1eb6b4
JB
142 struct gdb_xml_value *attr;
143
144 attr = xml_find_attribute (attributes, "name");
4d0fdd9b 145 item->filename = xstrdup ((const char *) attr->value.get ());
4d1eb6b4
JB
146
147 attr = xml_find_attribute (attributes, "member");
148 if (attr != NULL)
4d0fdd9b 149 item->member_name = xstrdup ((const char *) attr->value.get ());
4d1eb6b4
JB
150
151 attr = xml_find_attribute (attributes, "text_addr");
4d0fdd9b 152 item->text_addr = * (ULONGEST *) attr->value.get ();
4d1eb6b4
JB
153
154 attr = xml_find_attribute (attributes, "text_size");
4d0fdd9b 155 item->text_size = * (ULONGEST *) attr->value.get ();
4d1eb6b4
JB
156
157 attr = xml_find_attribute (attributes, "data_addr");
4d0fdd9b 158 item->data_addr = * (ULONGEST *) attr->value.get ();
4d1eb6b4
JB
159
160 attr = xml_find_attribute (attributes, "data_size");
4d0fdd9b 161 item->data_size = * (ULONGEST *) attr->value.get ();
4d1eb6b4 162
d0e449a1 163 VEC_safe_push (lm_info_aix_p, *list, item);
4d1eb6b4
JB
164}
165
8c56e112 166/* Handle the start of a <library-list-aix> element. */
4d1eb6b4
JB
167
168static void
169library_list_start_list (struct gdb_xml_parser *parser,
170 const struct gdb_xml_element *element,
4d0fdd9b
SM
171 void *user_data,
172 std::vector<gdb_xml_value> &attributes)
4d1eb6b4 173{
4d0fdd9b
SM
174 char *version
175 = (char *) xml_find_attribute (attributes, "version")->value.get ();
4d1eb6b4
JB
176
177 if (strcmp (version, "1.0") != 0)
178 gdb_xml_error (parser,
179 _("Library list has unsupported version \"%s\""),
180 version);
181}
182
183/* Discard the constructed library list. */
184
185static void
186solib_aix_free_library_list (void *p)
187{
d0e449a1
SM
188 VEC (lm_info_aix_p) **result = (VEC (lm_info_aix_p) **) p;
189 lm_info_aix *info;
4d1eb6b4
JB
190 int ix;
191
192 if (solib_aix_debug)
193 fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_library_list\n");
194
d0e449a1 195 for (ix = 0; VEC_iterate (lm_info_aix_p, *result, ix, info); ix++)
6c401f72
SM
196 delete info;
197
d0e449a1 198 VEC_free (lm_info_aix_p, *result);
4d1eb6b4
JB
199 *result = NULL;
200}
201
202/* The allowed elements and attributes for an AIX library list
8c56e112 203 described in XML format. The root element is a <library-list-aix>. */
4d1eb6b4
JB
204
205static const struct gdb_xml_attribute library_attributes[] =
206{
207 { "name", GDB_XML_AF_NONE, NULL, NULL },
208 { "member", GDB_XML_AF_OPTIONAL, NULL, NULL },
209 { "text_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
210 { "text_size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
211 { "data_addr", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
212 { "data_size", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
213 { NULL, GDB_XML_AF_NONE, NULL, NULL }
214};
215
216static const struct gdb_xml_element library_list_children[] =
217{
218 { "library", library_attributes, NULL,
219 GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
220 library_list_start_library, NULL},
221 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
222};
223
224static const struct gdb_xml_attribute library_list_attributes[] =
225{
226 { "version", GDB_XML_AF_NONE, NULL, NULL },
227 { NULL, GDB_XML_AF_NONE, NULL, NULL }
228};
229
230static const struct gdb_xml_element library_list_elements[] =
231{
8c56e112 232 { "library-list-aix", library_list_attributes, library_list_children,
4d1eb6b4
JB
233 GDB_XML_EF_NONE, library_list_start_list, NULL },
234 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
235};
236
237/* Parse LIBRARY, a string containing the loader info in XML format,
d0e449a1 238 and return an lm_info_aix_p vector.
4d1eb6b4
JB
239
240 Return NULL if the parsing failed. */
241
d0e449a1 242static VEC (lm_info_aix_p) *
4d1eb6b4
JB
243solib_aix_parse_libraries (const char *library)
244{
d0e449a1 245 VEC (lm_info_aix_p) *result = NULL;
72412762
TT
246 auto cleanup = make_scope_exit ([&] ()
247 {
248 solib_aix_free_library_list (&result);
249 });
4d1eb6b4
JB
250
251 if (gdb_xml_parse_quick (_("aix library list"), "library-list-aix.dtd",
252 library_list_elements, library, &result) == 0)
253 {
254 /* Parsed successfully, keep the result. */
72412762 255 cleanup.release ();
4d1eb6b4
JB
256 return result;
257 }
258
4d1eb6b4
JB
259 return NULL;
260}
261
262#endif /* HAVE_LIBEXPAT */
263
264/* Return the loader info for the given inferior (INF), or NULL if
265 the list could not be computed.
266
267 Cache the result in per-inferior data, so as to avoid recomputing it
268 each time this function is called.
269
270 If an error occurs while computing this list, and WARNING_MSG
271 is not NULL, then print a warning including WARNING_MSG and
272 a description of the error. */
273
d0e449a1 274static VEC (lm_info_aix_p) *
4d1eb6b4
JB
275solib_aix_get_library_list (struct inferior *inf, const char *warning_msg)
276{
277 struct solib_aix_inferior_data *data;
4d1eb6b4
JB
278
279 /* If already computed, return the cached value. */
280 data = get_solib_aix_inferior_data (inf);
281 if (data->library_list != NULL)
282 return data->library_list;
283
9018be22 284 gdb::optional<gdb::char_vector> library_document
8b88a78e 285 = target_read_stralloc (current_top_target (), TARGET_OBJECT_LIBRARIES_AIX,
b7b030ad 286 NULL);
9018be22 287 if (!library_document && warning_msg != NULL)
4d1eb6b4 288 {
ff99b71b 289 warning (_("%s (failed to read TARGET_OBJECT_LIBRARIES_AIX)"),
4d1eb6b4
JB
290 warning_msg);
291 return NULL;
292 }
4d1eb6b4
JB
293
294 if (solib_aix_debug)
295 fprintf_unfiltered (gdb_stdlog,
ff99b71b 296 "DEBUG: TARGET_OBJECT_LIBRARIES_AIX = \n%s\n",
9018be22 297 library_document->data ());
4d1eb6b4 298
9018be22 299 data->library_list = solib_aix_parse_libraries (library_document->data ());
4d1eb6b4
JB
300 if (data->library_list == NULL && warning_msg != NULL)
301 {
302 warning (_("%s (missing XML support?)"), warning_msg);
4d1eb6b4
JB
303 return NULL;
304 }
305
4d1eb6b4
JB
306 return data->library_list;
307}
308
309/* If the .bss section's VMA is set to an address located before
310 the end of the .data section, causing the two sections to overlap,
311 return the overlap in bytes. Otherwise, return zero.
312
313 Motivation:
314
315 The GNU linker sometimes sets the start address of the .bss session
316 before the end of the .data section, making the 2 sections overlap.
317 The loader appears to handle this situation gracefully, by simply
318 loading the bss section right after the end of the .data section.
319
320 This means that the .data and the .bss sections are sometimes
321 no longer relocated by the same amount. The problem is that
322 the ldinfo data does not contain any information regarding
323 the relocation of the .bss section, assuming that it would be
324 identical to the information provided for the .data section
325 (this is what would normally happen if the program was linked
326 correctly).
327
328 GDB therefore needs to detect those cases, and make the corresponding
329 adjustment to the .bss section offset computed from the ldinfo data
330 when necessary. This function returns the adjustment amount (or
331 zero when no adjustment is needed). */
332
333static CORE_ADDR
334solib_aix_bss_data_overlap (bfd *abfd)
335{
336 struct bfd_section *data_sect, *bss_sect;
337
338 data_sect = bfd_get_section_by_name (abfd, ".data");
339 if (data_sect == NULL)
340 return 0; /* No overlap possible. */
341
342 bss_sect = bfd_get_section_by_name (abfd, ".bss");
343 if (bss_sect == NULL)
344 return 0; /* No overlap possible. */
345
346 /* Assume the problem only occurs with linkers that place the .bss
347 section after the .data section (the problem has only been
348 observed when using the GNU linker, and the default linker
349 script always places the .data and .bss sections in that order). */
350 if (bfd_section_vma (abfd, bss_sect)
351 < bfd_section_vma (abfd, data_sect))
352 return 0;
353
354 if (bfd_section_vma (abfd, bss_sect)
355 < bfd_section_vma (abfd, data_sect) + bfd_get_section_size (data_sect))
356 return ((bfd_section_vma (abfd, data_sect)
357 + bfd_get_section_size (data_sect))
358 - bfd_section_vma (abfd, bss_sect));
359
360 return 0;
361}
362
363/* Implement the "relocate_section_addresses" target_so_ops method. */
364
365static void
366solib_aix_relocate_section_addresses (struct so_list *so,
367 struct target_section *sec)
368{
4d1eb6b4 369 struct bfd_section *bfd_sect = sec->the_bfd_section;
57e6060e 370 bfd *abfd = bfd_sect->owner;
4d1eb6b4 371 const char *section_name = bfd_section_name (abfd, bfd_sect);
d0e449a1 372 lm_info_aix *info = (lm_info_aix *) so->lm_info;
4d1eb6b4
JB
373
374 if (strcmp (section_name, ".text") == 0)
375 {
376 sec->addr = info->text_addr;
377 sec->endaddr = sec->addr + info->text_size;
378
379 /* The text address given to us by the loader contains
380 XCOFF headers, so we need to adjust by this much. */
381 sec->addr += bfd_sect->filepos;
382 }
383 else if (strcmp (section_name, ".data") == 0)
384 {
385 sec->addr = info->data_addr;
386 sec->endaddr = sec->addr + info->data_size;
387 }
388 else if (strcmp (section_name, ".bss") == 0)
389 {
060cfbef
JB
390 /* The information provided by the loader does not include
391 the address of the .bss section, but we know that it gets
392 relocated by the same offset as the .data section. So,
393 compute the relocation offset for the .data section, and
394 apply it to the .bss section as well. If the .data section
395 is not defined (which seems highly unlikely), do our best
396 by assuming no relocation. */
397 struct bfd_section *data_sect
398 = bfd_get_section_by_name (abfd, ".data");
399 CORE_ADDR data_offset = 0;
400
401 if (data_sect != NULL)
402 data_offset = info->data_addr - bfd_section_vma (abfd, data_sect);
403
404 sec->addr = bfd_section_vma (abfd, bfd_sect) + data_offset;
4d1eb6b4
JB
405 sec->addr += solib_aix_bss_data_overlap (abfd);
406 sec->endaddr = sec->addr + bfd_section_size (abfd, bfd_sect);
407 }
408 else
409 {
410 /* All other sections should not be relocated. */
4d1eb6b4
JB
411 sec->addr = bfd_section_vma (abfd, bfd_sect);
412 sec->endaddr = sec->addr + bfd_section_size (abfd, bfd_sect);
413 }
414}
415
416/* Implement the "free_so" target_so_ops method. */
417
418static void
419solib_aix_free_so (struct so_list *so)
420{
6c401f72
SM
421 lm_info_aix *li = (lm_info_aix *) so->lm_info;
422
4d1eb6b4
JB
423 if (solib_aix_debug)
424 fprintf_unfiltered (gdb_stdlog, "DEBUG: solib_aix_free_so (%s)\n",
425 so->so_name);
6c401f72
SM
426
427 delete li;
4d1eb6b4
JB
428}
429
430/* Implement the "clear_solib" target_so_ops method. */
431
432static void
433solib_aix_clear_solib (void)
434{
435 /* Nothing needed. */
436}
437
438/* Compute and return the OBJFILE's section_offset array, using
439 the associated loader info (INFO).
440
441 The resulting array is computed on the heap and must be
442 deallocated after use. */
443
f709fabb 444static gdb::unique_xmalloc_ptr<struct section_offsets>
4d1eb6b4 445solib_aix_get_section_offsets (struct objfile *objfile,
d0e449a1 446 lm_info_aix *info)
4d1eb6b4 447{
4d1eb6b4 448 bfd *abfd = objfile->obfd;
4d1eb6b4 449
f709fabb
TT
450 gdb::unique_xmalloc_ptr<struct section_offsets> offsets
451 (XCNEWVEC (struct section_offsets, objfile->num_sections));
4d1eb6b4
JB
452
453 /* .text */
454
455 if (objfile->sect_index_text != -1)
456 {
457 struct bfd_section *sect
458 = objfile->sections[objfile->sect_index_text].the_bfd_section;
459
460 offsets->offsets[objfile->sect_index_text]
461 = info->text_addr + sect->filepos - bfd_section_vma (abfd, sect);
462 }
463
464 /* .data */
465
466 if (objfile->sect_index_data != -1)
467 {
468 struct bfd_section *sect
469 = objfile->sections[objfile->sect_index_data].the_bfd_section;
470
471 offsets->offsets[objfile->sect_index_data]
472 = info->data_addr - bfd_section_vma (abfd, sect);
473 }
474
475 /* .bss
476
477 The offset of the .bss section should be identical to the offset
478 of the .data section. If no .data section (which seems hard to
479 believe it is possible), assume it is zero. */
480
481 if (objfile->sect_index_bss != -1
482 && objfile->sect_index_data != -1)
483 {
484 offsets->offsets[objfile->sect_index_bss]
485 = (offsets->offsets[objfile->sect_index_data]
486 + solib_aix_bss_data_overlap (abfd));
487 }
488
489 /* All other sections should not need relocation. */
490
491 return offsets;
492}
493
494/* Implement the "solib_create_inferior_hook" target_so_ops method. */
495
496static void
497solib_aix_solib_create_inferior_hook (int from_tty)
498{
499 const char *warning_msg = "unable to relocate main executable";
d0e449a1
SM
500 VEC (lm_info_aix_p) *library_list;
501 lm_info_aix *exec_info;
4d1eb6b4
JB
502
503 /* We need to relocate the main executable... */
504
505 library_list = solib_aix_get_library_list (current_inferior (),
506 warning_msg);
507 if (library_list == NULL)
508 return; /* Warning already printed. */
509
d0e449a1 510 if (VEC_length (lm_info_aix_p, library_list) < 1)
4d1eb6b4
JB
511 {
512 warning (_("unable to relocate main executable (no info from loader)"));
513 return;
514 }
515
d0e449a1 516 exec_info = VEC_index (lm_info_aix_p, library_list, 0);
4d1eb6b4
JB
517
518 if (symfile_objfile != NULL)
519 {
f709fabb 520 gdb::unique_xmalloc_ptr<struct section_offsets> offsets
4d1eb6b4 521 = solib_aix_get_section_offsets (symfile_objfile, exec_info);
4d1eb6b4 522
f709fabb 523 objfile_relocate (symfile_objfile, offsets.get ());
4d1eb6b4
JB
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.687141 seconds and 4 git commands to generate.