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