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