]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/solib-target.c
Remove old lint code
[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,
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
8b88a78e
PA
261 = target_read_stralloc (current_top_target (), TARGET_OBJECT_LIBRARIES,
262 NULL);
9018be22 263 if (!library_document)
cfa9d6d9
DJ
264 return NULL;
265
266 /* Parse the list. */
9018be22 267 library_list = solib_target_parse_libraries (library_document->data ());
b25d79d4 268
cfa9d6d9
DJ
269 if (library_list == NULL)
270 return NULL;
271
272 /* Build a struct so_list for each entry on the list. */
d0e449a1 273 for (ix = 0; VEC_iterate (lm_info_target_p, library_list, ix, info); ix++)
cfa9d6d9 274 {
41bf6aca 275 new_solib = XCNEW (struct so_list);
51046d9e
SM
276 strncpy (new_solib->so_name, info->name.c_str (),
277 SO_NAME_MAX_PATH_SIZE - 1);
cfa9d6d9 278 new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
51046d9e 279 strncpy (new_solib->so_original_name, info->name.c_str (),
cfa9d6d9
DJ
280 SO_NAME_MAX_PATH_SIZE - 1);
281 new_solib->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
282 new_solib->lm_info = info;
283
284 /* We no longer need this copy of the name. */
51046d9e 285 info->name.clear ();
cfa9d6d9
DJ
286
287 /* Add it to the list. */
288 if (!start)
289 last = start = new_solib;
290 else
291 {
292 last->next = new_solib;
293 last = new_solib;
294 }
295 }
296
297 /* Free the library list, but not its members. */
d0e449a1 298 VEC_free (lm_info_target_p, library_list);
cfa9d6d9
DJ
299
300 return start;
301}
302
cfa9d6d9 303static void
268a4a75 304solib_target_solib_create_inferior_hook (int from_tty)
cfa9d6d9
DJ
305{
306 /* Nothing needed. */
307}
308
309static void
310solib_target_clear_solib (void)
311{
312 /* Nothing needed. */
313}
314
315static void
316solib_target_free_so (struct so_list *so)
317{
d0e449a1
SM
318 lm_info_target *li = (lm_info_target *) so->lm_info;
319
51046d9e
SM
320 gdb_assert (li->name.empty ());
321
322 delete li;
cfa9d6d9
DJ
323}
324
325static void
326solib_target_relocate_section_addresses (struct so_list *so,
0542c86d 327 struct target_section *sec)
cfa9d6d9 328{
cfa9d6d9 329 CORE_ADDR offset;
d0e449a1 330 lm_info_target *li = (lm_info_target *) so->lm_info;
cfa9d6d9
DJ
331
332 /* Build the offset table only once per object file. We can not do
333 it any earlier, since we need to open the file first. */
d0e449a1 334 if (li->offsets == NULL)
cfa9d6d9 335 {
d445b2f6 336 int num_sections = gdb_bfd_count_sections (so->abfd);
cfa9d6d9 337
d0e449a1 338 li->offsets
224c3ddb
SM
339 = ((struct section_offsets *)
340 xzalloc (SIZEOF_N_SECTION_OFFSETS (num_sections)));
cfa9d6d9 341
f2f46dfc 342 if (!li->section_bases.empty ())
cfa9d6d9 343 {
cfa9d6d9 344 int i;
1fddbabb 345 asection *sect;
1fddbabb
PA
346 int num_alloc_sections = 0;
347
348 for (i = 0, sect = so->abfd->sections;
349 sect != NULL;
350 i++, sect = sect->next)
351 if ((bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
352 num_alloc_sections++;
353
d17f7b36 354 if (num_alloc_sections != li->section_bases.size ())
1fddbabb
PA
355 warning (_("\
356Could not relocate shared library \"%s\": wrong number of ALLOC sections"),
cfa9d6d9 357 so->so_name);
1fddbabb 358 else
cfa9d6d9 359 {
1fddbabb
PA
360 int bases_index = 0;
361 int found_range = 0;
1fddbabb
PA
362
363 so->addr_low = ~(CORE_ADDR) 0;
364 so->addr_high = 0;
365 for (i = 0, sect = so->abfd->sections;
366 sect != NULL;
367 i++, sect = sect->next)
368 {
369 if (!(bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
370 continue;
371 if (bfd_section_size (so->abfd, sect) > 0)
372 {
373 CORE_ADDR low, high;
433759f7 374
f2f46dfc 375 low = li->section_bases[i];
1fddbabb
PA
376 high = low + bfd_section_size (so->abfd, sect) - 1;
377
378 if (low < so->addr_low)
379 so->addr_low = low;
380 if (high > so->addr_high)
381 so->addr_high = high;
382 gdb_assert (so->addr_low <= so->addr_high);
383 found_range = 1;
384 }
f2f46dfc 385 li->offsets->offsets[i] = li->section_bases[bases_index];
1fddbabb
PA
386 bases_index++;
387 }
388 if (!found_range)
389 so->addr_low = so->addr_high = 0;
390 gdb_assert (so->addr_low <= so->addr_high);
391 }
392 }
f2f46dfc 393 else if (!li->segment_bases.empty ())
1fddbabb
PA
394 {
395 struct symfile_segment_data *data;
433759f7 396
1fddbabb
PA
397 data = get_symfile_segment_data (so->abfd);
398 if (data == NULL)
399 warning (_("\
400Could not relocate shared library \"%s\": no segments"), so->so_name);
401 else
402 {
403 ULONGEST orig_delta;
404 int i;
1fddbabb 405
d0e449a1 406 if (!symfile_map_offsets_to_segments (so->abfd, data, li->offsets,
d17f7b36
SM
407 li->segment_bases.size (),
408 li->segment_bases.data ()))
1fddbabb
PA
409 warning (_("\
410Could not relocate shared library \"%s\": bad offsets"), so->so_name);
411
412 /* Find the range of addresses to report for this library in
413 "info sharedlibrary". Report any consecutive segments
414 which were relocated as a single unit. */
d17f7b36
SM
415 gdb_assert (li->segment_bases.size () > 0);
416 orig_delta = li->segment_bases[0] - data->segment_bases[0];
1fddbabb
PA
417
418 for (i = 1; i < data->num_segments; i++)
419 {
420 /* If we have run out of offsets, assume all
421 remaining segments have the same offset. */
d17f7b36 422 if (i >= li->segment_bases.size ())
1fddbabb
PA
423 continue;
424
425 /* If this segment does not have the same offset, do
426 not include it in the library's range. */
d17f7b36
SM
427 if (li->segment_bases[i] - data->segment_bases[i]
428 != orig_delta)
1fddbabb
PA
429 break;
430 }
431
d17f7b36 432 so->addr_low = li->segment_bases[0];
1fddbabb
PA
433 so->addr_high = (data->segment_bases[i - 1]
434 + data->segment_sizes[i - 1]
435 + orig_delta);
436 gdb_assert (so->addr_low <= so->addr_high);
437
438 free_symfile_segment_data (data);
cfa9d6d9 439 }
cfa9d6d9
DJ
440 }
441 }
442
d0e449a1
SM
443 offset = li->offsets->offsets[gdb_bfd_section_index
444 (sec->the_bfd_section->owner,
445 sec->the_bfd_section)];
cfa9d6d9
DJ
446 sec->addr += offset;
447 sec->endaddr += offset;
448}
449
450static int
bf469271 451solib_target_open_symbol_file_object (int from_tty)
cfa9d6d9
DJ
452{
453 /* We can't locate the main symbol file based on the target's
454 knowledge; the user has to specify it. */
455 return 0;
456}
457
458static int
459solib_target_in_dynsym_resolve_code (CORE_ADDR pc)
460{
461 /* We don't have a range of addresses for the dynamic linker; there
462 may not be one in the program's address space. So only report
463 PLT entries (which may be import stubs). */
3e5d3a5a 464 return in_plt_section (pc);
cfa9d6d9
DJ
465}
466
8d465389 467struct target_so_ops solib_target_so_ops;
cfa9d6d9 468
cfa9d6d9
DJ
469void
470_initialize_solib_target (void)
471{
472 solib_target_so_ops.relocate_section_addresses
473 = solib_target_relocate_section_addresses;
474 solib_target_so_ops.free_so = solib_target_free_so;
475 solib_target_so_ops.clear_solib = solib_target_clear_solib;
476 solib_target_so_ops.solib_create_inferior_hook
477 = solib_target_solib_create_inferior_hook;
cfa9d6d9
DJ
478 solib_target_so_ops.current_sos = solib_target_current_sos;
479 solib_target_so_ops.open_symbol_file_object
480 = solib_target_open_symbol_file_object;
481 solib_target_so_ops.in_dynsym_resolve_code
482 = solib_target_in_dynsym_resolve_code;
831a0c44 483 solib_target_so_ops.bfd_open = solib_bfd_open;
98d64339
PA
484
485 /* Set current_target_so_ops to solib_target_so_ops if not already
486 set. */
487 if (current_target_so_ops == 0)
488 current_target_so_ops = &solib_target_so_ops;
cfa9d6d9 489}