Change return type of gdbarch_software_single_step to vector<CORE_ADDR>
[deliverable/binutils-gdb.git] / gdb / solib-target.c
CommitLineData
cfa9d6d9
DJ
1/* Definitions for targets which report shared library events.
2
61baf725 3 Copyright (C) 2007-2017 Free Software Foundation, Inc.
cfa9d6d9
DJ
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
cfa9d6d9
DJ
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
cfa9d6d9
DJ
19
20#include "defs.h"
21#include "objfiles.h"
22#include "solist.h"
23#include "symtab.h"
24#include "symfile.h"
25#include "target.h"
26#include "vec.h"
8d465389 27#include "solib-target.h"
cfa9d6d9 28
cfa9d6d9 29/* Private data for each loaded library. */
d0e449a1 30struct lm_info_target : public lm_info_base
cfa9d6d9 31{
51046d9e
SM
32 ~lm_info_target ()
33 {
34 VEC_free (CORE_ADDR, this->segment_bases);
35 VEC_free (CORE_ADDR, this->section_bases);
36 }
37
cfa9d6d9
DJ
38 /* The library's name. The name is normally kept in the struct
39 so_list; it is only here during XML parsing. */
51046d9e 40 std::string name;
cfa9d6d9 41
1fddbabb
PA
42 /* The target can either specify segment bases or section bases, not
43 both. */
44
cfa9d6d9
DJ
45 /* The base addresses for each independently relocatable segment of
46 this shared library. */
51046d9e 47 VEC(CORE_ADDR) *segment_bases = NULL;
cfa9d6d9 48
1fddbabb
PA
49 /* The base addresses for each independently allocatable,
50 relocatable section of this shared library. */
51046d9e 51 VEC(CORE_ADDR) *section_bases = NULL;
1fddbabb 52
cfa9d6d9 53 /* The cached offsets for each section of this shared library,
1fddbabb 54 determined from SEGMENT_BASES, or SECTION_BASES. */
51046d9e 55 section_offsets *offsets = NULL;
cfa9d6d9
DJ
56};
57
d0e449a1
SM
58typedef lm_info_target *lm_info_target_p;
59DEF_VEC_P(lm_info_target_p);
cfa9d6d9
DJ
60
61#if !defined(HAVE_LIBEXPAT)
62
d0e449a1 63static VEC(lm_info_target_p) *
cfa9d6d9
DJ
64solib_target_parse_libraries (const char *library)
65{
66 static int have_warned;
67
68 if (!have_warned)
69 {
70 have_warned = 1;
71 warning (_("Can not parse XML library list; XML support was disabled "
72 "at compile time"));
73 }
74
75 return NULL;
76}
77
78#else /* HAVE_LIBEXPAT */
79
80#include "xml-support.h"
81
82/* Handle the start of a <segment> element. */
83
84static void
85library_list_start_segment (struct gdb_xml_parser *parser,
86 const struct gdb_xml_element *element,
87 void *user_data, VEC(gdb_xml_value_s) *attributes)
88{
d0e449a1
SM
89 VEC(lm_info_target_p) **list = (VEC(lm_info_target_p) **) user_data;
90 lm_info_target *last = VEC_last (lm_info_target_p, *list);
19ba03f4 91 ULONGEST *address_p
bc84451b 92 = (ULONGEST *) xml_find_attribute (attributes, "address")->value;
358eb95e 93 CORE_ADDR address = (CORE_ADDR) *address_p;
cfa9d6d9 94
1fddbabb
PA
95 if (last->section_bases != NULL)
96 gdb_xml_error (parser,
97 _("Library list with both segments and sections"));
98
267f6504 99 VEC_safe_push (CORE_ADDR, last->segment_bases, address);
cfa9d6d9
DJ
100}
101
1fddbabb
PA
102static void
103library_list_start_section (struct gdb_xml_parser *parser,
104 const struct gdb_xml_element *element,
105 void *user_data, VEC(gdb_xml_value_s) *attributes)
106{
d0e449a1
SM
107 VEC(lm_info_target_p) **list = (VEC(lm_info_target_p) **) user_data;
108 lm_info_target *last = VEC_last (lm_info_target_p, *list);
19ba03f4 109 ULONGEST *address_p
bc84451b 110 = (ULONGEST *) xml_find_attribute (attributes, "address")->value;
1fddbabb
PA
111 CORE_ADDR address = (CORE_ADDR) *address_p;
112
113 if (last->segment_bases != NULL)
114 gdb_xml_error (parser,
115 _("Library list with both segments and sections"));
116
267f6504 117 VEC_safe_push (CORE_ADDR, last->section_bases, address);
1fddbabb
PA
118}
119
cfa9d6d9
DJ
120/* Handle the start of a <library> element. */
121
122static void
123library_list_start_library (struct gdb_xml_parser *parser,
124 const struct gdb_xml_element *element,
125 void *user_data, VEC(gdb_xml_value_s) *attributes)
126{
d0e449a1 127 VEC(lm_info_target_p) **list = (VEC(lm_info_target_p) **) user_data;
51046d9e 128 lm_info_target *item = new lm_info_target;
19ba03f4
SM
129 const char *name
130 = (const char *) xml_find_attribute (attributes, "name")->value;
cfa9d6d9
DJ
131
132 item->name = xstrdup (name);
d0e449a1 133 VEC_safe_push (lm_info_target_p, *list, item);
cfa9d6d9
DJ
134}
135
1fddbabb
PA
136static void
137library_list_end_library (struct gdb_xml_parser *parser,
138 const struct gdb_xml_element *element,
139 void *user_data, const char *body_text)
140{
d0e449a1
SM
141 VEC(lm_info_target_p) **list = (VEC(lm_info_target_p) **) user_data;
142 lm_info_target *lm_info = VEC_last (lm_info_target_p, *list);
433759f7 143
1fddbabb
PA
144 if (lm_info->segment_bases == NULL
145 && lm_info->section_bases == NULL)
146 gdb_xml_error (parser,
147 _("No segment or section bases defined"));
148}
149
150
cfa9d6d9
DJ
151/* Handle the start of a <library-list> element. */
152
153static void
154library_list_start_list (struct gdb_xml_parser *parser,
155 const struct gdb_xml_element *element,
156 void *user_data, VEC(gdb_xml_value_s) *attributes)
157{
24c05f46 158 struct gdb_xml_value *version = xml_find_attribute (attributes, "version");
cfa9d6d9 159
24c05f46 160 /* #FIXED attribute may be omitted, Expat returns NULL in such case. */
8847cac2 161 if (version != NULL)
24c05f46 162 {
19ba03f4 163 const char *string = (const char *) version->value;
24c05f46
JK
164
165 if (strcmp (string, "1.0") != 0)
166 gdb_xml_error (parser,
167 _("Library list has unsupported version \"%s\""),
21047726 168 string);
24c05f46 169 }
cfa9d6d9
DJ
170}
171
172/* Discard the constructed library list. */
173
174static void
175solib_target_free_library_list (void *p)
176{
d0e449a1
SM
177 VEC(lm_info_target_p) **result = (VEC(lm_info_target_p) **) p;
178 lm_info_target *info;
cfa9d6d9
DJ
179 int ix;
180
d0e449a1 181 for (ix = 0; VEC_iterate (lm_info_target_p, *result, ix, info); ix++)
51046d9e
SM
182 delete info;
183
d0e449a1 184 VEC_free (lm_info_target_p, *result);
cfa9d6d9
DJ
185 *result = NULL;
186}
187
188/* The allowed elements and attributes for an XML library list.
189 The root element is a <library-list>. */
190
d6c10e95 191static const struct gdb_xml_attribute segment_attributes[] = {
cfa9d6d9
DJ
192 { "address", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
193 { NULL, GDB_XML_AF_NONE, NULL, NULL }
194};
195
d6c10e95 196static const struct gdb_xml_attribute section_attributes[] = {
1fddbabb
PA
197 { "address", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
198 { NULL, GDB_XML_AF_NONE, NULL, NULL }
199};
200
d6c10e95 201static const struct gdb_xml_element library_children[] = {
1fddbabb
PA
202 { "segment", segment_attributes, NULL,
203 GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
cfa9d6d9 204 library_list_start_segment, NULL },
1fddbabb
PA
205 { "section", section_attributes, NULL,
206 GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
207 library_list_start_section, NULL },
cfa9d6d9
DJ
208 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
209};
210
d6c10e95 211static const struct gdb_xml_attribute library_attributes[] = {
cfa9d6d9
DJ
212 { "name", GDB_XML_AF_NONE, NULL, NULL },
213 { NULL, GDB_XML_AF_NONE, NULL, NULL }
214};
215
d6c10e95 216static const struct gdb_xml_element library_list_children[] = {
cfa9d6d9
DJ
217 { "library", library_attributes, library_children,
218 GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
1fddbabb 219 library_list_start_library, library_list_end_library },
cfa9d6d9
DJ
220 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
221};
222
d6c10e95 223static const struct gdb_xml_attribute library_list_attributes[] = {
24c05f46 224 { "version", GDB_XML_AF_OPTIONAL, NULL, NULL },
cfa9d6d9
DJ
225 { NULL, GDB_XML_AF_NONE, NULL, NULL }
226};
227
d6c10e95 228static const struct gdb_xml_element library_list_elements[] = {
cfa9d6d9
DJ
229 { "library-list", library_list_attributes, library_list_children,
230 GDB_XML_EF_NONE, library_list_start_list, NULL },
231 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
232};
233
d0e449a1 234static VEC(lm_info_target_p) *
cfa9d6d9
DJ
235solib_target_parse_libraries (const char *library)
236{
d0e449a1 237 VEC(lm_info_target_p) *result = NULL;
efc0eabd
PA
238 struct cleanup *back_to = make_cleanup (solib_target_free_library_list,
239 &result);
cfa9d6d9 240
efc0eabd
PA
241 if (gdb_xml_parse_quick (_("target library list"), "library-list.dtd",
242 library_list_elements, library, &result) == 0)
243 {
244 /* Parsed successfully, keep the result. */
245 discard_cleanups (back_to);
246 return result;
247 }
cfa9d6d9
DJ
248
249 do_cleanups (back_to);
efc0eabd 250 return NULL;
cfa9d6d9
DJ
251}
252#endif
253
254static struct so_list *
255solib_target_current_sos (void)
256{
257 struct so_list *new_solib, *start = NULL, *last = NULL;
b25d79d4
PM
258 char *library_document;
259 struct cleanup *old_chain;
d0e449a1
SM
260 VEC(lm_info_target_p) *library_list;
261 lm_info_target *info;
cfa9d6d9
DJ
262 int ix;
263
264 /* Fetch the list of shared libraries. */
265 library_document = target_read_stralloc (&current_target,
266 TARGET_OBJECT_LIBRARIES,
267 NULL);
268 if (library_document == NULL)
269 return NULL;
270
b25d79d4
PM
271 /* solib_target_parse_libraries may throw, so we use a cleanup. */
272 old_chain = make_cleanup (xfree, library_document);
273
cfa9d6d9
DJ
274 /* Parse the list. */
275 library_list = solib_target_parse_libraries (library_document);
b25d79d4
PM
276
277 /* library_document string is not needed behind this point. */
278 do_cleanups (old_chain);
279
cfa9d6d9
DJ
280 if (library_list == NULL)
281 return NULL;
282
283 /* Build a struct so_list for each entry on the list. */
d0e449a1 284 for (ix = 0; VEC_iterate (lm_info_target_p, library_list, ix, info); ix++)
cfa9d6d9 285 {
41bf6aca 286 new_solib = XCNEW (struct so_list);
51046d9e
SM
287 strncpy (new_solib->so_name, info->name.c_str (),
288 SO_NAME_MAX_PATH_SIZE - 1);
cfa9d6d9 289 new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
51046d9e 290 strncpy (new_solib->so_original_name, info->name.c_str (),
cfa9d6d9
DJ
291 SO_NAME_MAX_PATH_SIZE - 1);
292 new_solib->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
293 new_solib->lm_info = info;
294
295 /* We no longer need this copy of the name. */
51046d9e 296 info->name.clear ();
cfa9d6d9
DJ
297
298 /* Add it to the list. */
299 if (!start)
300 last = start = new_solib;
301 else
302 {
303 last->next = new_solib;
304 last = new_solib;
305 }
306 }
307
308 /* Free the library list, but not its members. */
d0e449a1 309 VEC_free (lm_info_target_p, library_list);
cfa9d6d9
DJ
310
311 return start;
312}
313
cfa9d6d9 314static void
268a4a75 315solib_target_solib_create_inferior_hook (int from_tty)
cfa9d6d9
DJ
316{
317 /* Nothing needed. */
318}
319
320static void
321solib_target_clear_solib (void)
322{
323 /* Nothing needed. */
324}
325
326static void
327solib_target_free_so (struct so_list *so)
328{
d0e449a1
SM
329 lm_info_target *li = (lm_info_target *) so->lm_info;
330
51046d9e
SM
331 gdb_assert (li->name.empty ());
332
333 delete li;
cfa9d6d9
DJ
334}
335
336static void
337solib_target_relocate_section_addresses (struct so_list *so,
0542c86d 338 struct target_section *sec)
cfa9d6d9 339{
cfa9d6d9 340 CORE_ADDR offset;
d0e449a1 341 lm_info_target *li = (lm_info_target *) so->lm_info;
cfa9d6d9
DJ
342
343 /* Build the offset table only once per object file. We can not do
344 it any earlier, since we need to open the file first. */
d0e449a1 345 if (li->offsets == NULL)
cfa9d6d9 346 {
d445b2f6 347 int num_sections = gdb_bfd_count_sections (so->abfd);
cfa9d6d9 348
d0e449a1 349 li->offsets
224c3ddb
SM
350 = ((struct section_offsets *)
351 xzalloc (SIZEOF_N_SECTION_OFFSETS (num_sections)));
cfa9d6d9 352
d0e449a1 353 if (li->section_bases)
cfa9d6d9 354 {
cfa9d6d9 355 int i;
1fddbabb
PA
356 asection *sect;
357 int num_section_bases
d0e449a1 358 = VEC_length (CORE_ADDR, li->section_bases);
1fddbabb
PA
359 int num_alloc_sections = 0;
360
361 for (i = 0, sect = so->abfd->sections;
362 sect != NULL;
363 i++, sect = sect->next)
364 if ((bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
365 num_alloc_sections++;
366
367 if (num_alloc_sections != num_section_bases)
368 warning (_("\
369Could not relocate shared library \"%s\": wrong number of ALLOC sections"),
cfa9d6d9 370 so->so_name);
1fddbabb 371 else
cfa9d6d9 372 {
1fddbabb
PA
373 int bases_index = 0;
374 int found_range = 0;
375 CORE_ADDR *section_bases;
433759f7 376
1fddbabb 377 section_bases = VEC_address (CORE_ADDR,
d0e449a1 378 li->section_bases);
1fddbabb
PA
379
380 so->addr_low = ~(CORE_ADDR) 0;
381 so->addr_high = 0;
382 for (i = 0, sect = so->abfd->sections;
383 sect != NULL;
384 i++, sect = sect->next)
385 {
386 if (!(bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
387 continue;
388 if (bfd_section_size (so->abfd, sect) > 0)
389 {
390 CORE_ADDR low, high;
433759f7 391
1fddbabb
PA
392 low = section_bases[i];
393 high = low + bfd_section_size (so->abfd, sect) - 1;
394
395 if (low < so->addr_low)
396 so->addr_low = low;
397 if (high > so->addr_high)
398 so->addr_high = high;
399 gdb_assert (so->addr_low <= so->addr_high);
400 found_range = 1;
401 }
d0e449a1 402 li->offsets->offsets[i]
3e43a32a 403 = section_bases[bases_index];
1fddbabb
PA
404 bases_index++;
405 }
406 if (!found_range)
407 so->addr_low = so->addr_high = 0;
408 gdb_assert (so->addr_low <= so->addr_high);
409 }
410 }
d0e449a1 411 else if (li->segment_bases)
1fddbabb
PA
412 {
413 struct symfile_segment_data *data;
433759f7 414
1fddbabb
PA
415 data = get_symfile_segment_data (so->abfd);
416 if (data == NULL)
417 warning (_("\
418Could not relocate shared library \"%s\": no segments"), so->so_name);
419 else
420 {
421 ULONGEST orig_delta;
422 int i;
423 int num_bases;
424 CORE_ADDR *segment_bases;
425
d0e449a1
SM
426 num_bases = VEC_length (CORE_ADDR, li->segment_bases);
427 segment_bases = VEC_address (CORE_ADDR, li->segment_bases);
1fddbabb 428
d0e449a1 429 if (!symfile_map_offsets_to_segments (so->abfd, data, li->offsets,
1fddbabb
PA
430 num_bases, segment_bases))
431 warning (_("\
432Could not relocate shared library \"%s\": bad offsets"), so->so_name);
433
434 /* Find the range of addresses to report for this library in
435 "info sharedlibrary". Report any consecutive segments
436 which were relocated as a single unit. */
437 gdb_assert (num_bases > 0);
438 orig_delta = segment_bases[0] - data->segment_bases[0];
439
440 for (i = 1; i < data->num_segments; i++)
441 {
442 /* If we have run out of offsets, assume all
443 remaining segments have the same offset. */
444 if (i >= num_bases)
445 continue;
446
447 /* If this segment does not have the same offset, do
448 not include it in the library's range. */
449 if (segment_bases[i] - data->segment_bases[i] != orig_delta)
450 break;
451 }
452
453 so->addr_low = segment_bases[0];
454 so->addr_high = (data->segment_bases[i - 1]
455 + data->segment_sizes[i - 1]
456 + orig_delta);
457 gdb_assert (so->addr_low <= so->addr_high);
458
459 free_symfile_segment_data (data);
cfa9d6d9 460 }
cfa9d6d9
DJ
461 }
462 }
463
d0e449a1
SM
464 offset = li->offsets->offsets[gdb_bfd_section_index
465 (sec->the_bfd_section->owner,
466 sec->the_bfd_section)];
cfa9d6d9
DJ
467 sec->addr += offset;
468 sec->endaddr += offset;
469}
470
471static int
472solib_target_open_symbol_file_object (void *from_ttyp)
473{
474 /* We can't locate the main symbol file based on the target's
475 knowledge; the user has to specify it. */
476 return 0;
477}
478
479static int
480solib_target_in_dynsym_resolve_code (CORE_ADDR pc)
481{
482 /* We don't have a range of addresses for the dynamic linker; there
483 may not be one in the program's address space. So only report
484 PLT entries (which may be import stubs). */
3e5d3a5a 485 return in_plt_section (pc);
cfa9d6d9
DJ
486}
487
8d465389 488struct target_so_ops solib_target_so_ops;
cfa9d6d9 489
3e43a32a
MS
490/* -Wmissing-prototypes */
491extern initialize_file_ftype _initialize_solib_target;
cfa9d6d9
DJ
492
493void
494_initialize_solib_target (void)
495{
496 solib_target_so_ops.relocate_section_addresses
497 = solib_target_relocate_section_addresses;
498 solib_target_so_ops.free_so = solib_target_free_so;
499 solib_target_so_ops.clear_solib = solib_target_clear_solib;
500 solib_target_so_ops.solib_create_inferior_hook
501 = solib_target_solib_create_inferior_hook;
cfa9d6d9
DJ
502 solib_target_so_ops.current_sos = solib_target_current_sos;
503 solib_target_so_ops.open_symbol_file_object
504 = solib_target_open_symbol_file_object;
505 solib_target_so_ops.in_dynsym_resolve_code
506 = solib_target_in_dynsym_resolve_code;
831a0c44 507 solib_target_so_ops.bfd_open = solib_bfd_open;
98d64339
PA
508
509 /* Set current_target_so_ops to solib_target_so_ops if not already
510 set. */
511 if (current_target_so_ops == 0)
512 current_target_so_ops = &solib_target_so_ops;
cfa9d6d9 513}
This page took 1.004149 seconds and 4 git commands to generate.