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