GDB (xrefs)
/tmp/gdb-7.10/gdb/solib-target.c
Go to the documentation of this file.
1 /* Definitions for targets which report shared library events.
2 
3  Copyright (C) 2007-2015 Free Software Foundation, Inc.
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
9  the Free Software Foundation; either version 3 of the License, or
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
18  along with this program. If not, see <http://www.gnu.org/licenses/>. */
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"
27 #include "solib-target.h"
28 
29 /* Private data for each loaded library. */
30 struct 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 
36  /* The target can either specify segment bases or section bases, not
37  both. */
38 
39  /* The base addresses for each independently relocatable segment of
40  this shared library. */
41  VEC(CORE_ADDR) *segment_bases;
42 
43  /* The base addresses for each independently allocatable,
44  relocatable section of this shared library. */
45  VEC(CORE_ADDR) *section_bases;
46 
47  /* The cached offsets for each section of this shared library,
48  determined from SEGMENT_BASES, or SECTION_BASES. */
49  struct section_offsets *offsets;
50 };
51 
52 typedef struct lm_info *lm_info_p;
53 DEF_VEC_P(lm_info_p);
54 
55 #if !defined(HAVE_LIBEXPAT)
56 
57 static VEC(lm_info_p) *
58 solib_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 
78 static void
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);
85  ULONGEST *address_p = xml_find_attribute (attributes, "address")->value;
86  CORE_ADDR address = (CORE_ADDR) *address_p;
87 
88  if (last->section_bases != NULL)
89  gdb_xml_error (parser,
90  _("Library list with both segments and sections"));
91 
92  VEC_safe_push (CORE_ADDR, last->segment_bases, address);
93 }
94 
95 static void
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);
102  ULONGEST *address_p = xml_find_attribute (attributes, "address")->value;
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 
109  VEC_safe_push (CORE_ADDR, last->section_bases, address);
110 }
111 
112 /* Handle the start of a <library> element. */
113 
114 static void
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;
120  struct lm_info *item = XCNEW (struct lm_info);
121  const char *name = xml_find_attribute (attributes, "name")->value;
122 
123  item->name = xstrdup (name);
124  VEC_safe_push (lm_info_p, *list, item);
125 }
126 
127 static void
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);
134 
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 
142 /* Handle the start of a <library-list> element. */
143 
144 static void
146  const struct gdb_xml_element *element,
147  void *user_data, VEC(gdb_xml_value_s) *attributes)
148 {
149  struct gdb_xml_value *version = xml_find_attribute (attributes, "version");
150 
151  /* #FIXED attribute may be omitted, Expat returns NULL in such case. */
152  if (version != NULL)
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  }
161 }
162 
163 /* Discard the constructed library list. */
164 
165 static void
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);
176  VEC_free (CORE_ADDR, info->section_bases);
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 
186 static const struct gdb_xml_attribute segment_attributes[] = {
187  { "address", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
188  { NULL, GDB_XML_AF_NONE, NULL, NULL }
189 };
190 
191 static const struct gdb_xml_attribute section_attributes[] = {
192  { "address", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
193  { NULL, GDB_XML_AF_NONE, NULL, NULL }
194 };
195 
196 static const struct gdb_xml_element library_children[] = {
197  { "segment", segment_attributes, NULL,
200  { "section", section_attributes, NULL,
203  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
204 };
205 
206 static const struct gdb_xml_attribute library_attributes[] = {
207  { "name", GDB_XML_AF_NONE, NULL, NULL },
208  { NULL, GDB_XML_AF_NONE, NULL, NULL }
209 };
210 
211 static const struct gdb_xml_element library_list_children[] = {
212  { "library", library_attributes, library_children,
215  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
216 };
217 
218 static const struct gdb_xml_attribute library_list_attributes[] = {
219  { "version", GDB_XML_AF_OPTIONAL, NULL, NULL },
220  { NULL, GDB_XML_AF_NONE, NULL, NULL }
221 };
222 
223 static const struct gdb_xml_element library_list_elements[] = {
226  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
227 };
228 
229 static VEC(lm_info_p) *
230 solib_target_parse_libraries (const char *library)
231 {
232  VEC(lm_info_p) *result = NULL;
234  &result);
235 
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  }
243 
244  do_cleanups (back_to);
245  return NULL;
246 }
247 #endif
248 
249 static struct so_list *
251 {
252  struct so_list *new_solib, *start = NULL, *last = NULL;
253  char *library_document;
254  struct cleanup *old_chain;
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,
262  NULL);
263  if (library_document == NULL)
264  return NULL;
265 
266  /* solib_target_parse_libraries may throw, so we use a cleanup. */
267  old_chain = make_cleanup (xfree, library_document);
268 
269  /* Parse the list. */
270  library_list = solib_target_parse_libraries (library_document);
271 
272  /* library_document string is not needed behind this point. */
273  do_cleanups (old_chain);
274 
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  {
281  new_solib = XCNEW (struct so_list);
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,
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 
309 static void
311 {
312  /* Nothing needed. */
313 }
314 
315 static void
317 {
318  /* Nothing needed. */
319 }
320 
321 static void
323 {
324  /* Nothing needed. */
325 }
326 
327 static void
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 
336 static void
338  struct target_section *sec)
339 {
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  {
346  int num_sections = gdb_bfd_count_sections (so->abfd);
347 
348  so->lm_info->offsets = xzalloc (SIZEOF_N_SECTION_OFFSETS (num_sections));
349 
350  if (so->lm_info->section_bases)
351  {
352  int i;
353  asection *sect;
354  int num_section_bases
355  = VEC_length (CORE_ADDR, so->lm_info->section_bases);
356  int num_alloc_sections = 0;
357 
358  for (i = 0, sect = so->abfd->sections;
359  sect != NULL;
360  i++, sect = sect->next)
361  if ((bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
362  num_alloc_sections++;
363 
364  if (num_alloc_sections != num_section_bases)
365  warning (_("\
366 Could not relocate shared library \"%s\": wrong number of ALLOC sections"),
367  so->so_name);
368  else
369  {
370  int bases_index = 0;
371  int found_range = 0;
372  CORE_ADDR *section_bases;
373 
374  section_bases = VEC_address (CORE_ADDR,
375  so->lm_info->section_bases);
376 
377  so->addr_low = ~(CORE_ADDR) 0;
378  so->addr_high = 0;
379  for (i = 0, sect = so->abfd->sections;
380  sect != NULL;
381  i++, sect = sect->next)
382  {
383  if (!(bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
384  continue;
385  if (bfd_section_size (so->abfd, sect) > 0)
386  {
387  CORE_ADDR low, high;
388 
389  low = section_bases[i];
390  high = low + bfd_section_size (so->abfd, sect) - 1;
391 
392  if (low < so->addr_low)
393  so->addr_low = low;
394  if (high > so->addr_high)
395  so->addr_high = high;
396  gdb_assert (so->addr_low <= so->addr_high);
397  found_range = 1;
398  }
399  so->lm_info->offsets->offsets[i]
400  = section_bases[bases_index];
401  bases_index++;
402  }
403  if (!found_range)
404  so->addr_low = so->addr_high = 0;
405  gdb_assert (so->addr_low <= so->addr_high);
406  }
407  }
408  else if (so->lm_info->segment_bases)
409  {
410  struct symfile_segment_data *data;
411 
412  data = get_symfile_segment_data (so->abfd);
413  if (data == NULL)
414  warning (_("\
415 Could not relocate shared library \"%s\": no segments"), so->so_name);
416  else
417  {
418  ULONGEST orig_delta;
419  int i;
420  int num_bases;
422 
423  num_bases = VEC_length (CORE_ADDR, so->lm_info->segment_bases);
424  segment_bases = VEC_address (CORE_ADDR,
425  so->lm_info->segment_bases);
426 
427  if (!symfile_map_offsets_to_segments (so->abfd, data,
428  so->lm_info->offsets,
429  num_bases, segment_bases))
430  warning (_("\
431 Could not relocate shared library \"%s\": bad offsets"), so->so_name);
432 
433  /* Find the range of addresses to report for this library in
434  "info sharedlibrary". Report any consecutive segments
435  which were relocated as a single unit. */
436  gdb_assert (num_bases > 0);
437  orig_delta = segment_bases[0] - data->segment_bases[0];
438 
439  for (i = 1; i < data->num_segments; i++)
440  {
441  /* If we have run out of offsets, assume all
442  remaining segments have the same offset. */
443  if (i >= num_bases)
444  continue;
445 
446  /* If this segment does not have the same offset, do
447  not include it in the library's range. */
448  if (segment_bases[i] - data->segment_bases[i] != orig_delta)
449  break;
450  }
451 
452  so->addr_low = segment_bases[0];
453  so->addr_high = (data->segment_bases[i - 1]
454  + data->segment_sizes[i - 1]
455  + orig_delta);
456  gdb_assert (so->addr_low <= so->addr_high);
457 
459  }
460  }
461  }
462 
463  offset = so->lm_info->offsets->offsets[gdb_bfd_section_index
464  (sec->the_bfd_section->owner,
465  sec->the_bfd_section)];
466  sec->addr += offset;
467  sec->endaddr += offset;
468 }
469 
470 static int
472 {
473  /* We can't locate the main symbol file based on the target's
474  knowledge; the user has to specify it. */
475  return 0;
476 }
477 
478 static int
480 {
481  /* We don't have a range of addresses for the dynamic linker; there
482  may not be one in the program's address space. So only report
483  PLT entries (which may be import stubs). */
484  return in_plt_section (pc);
485 }
486 
488 
489 /* -Wmissing-prototypes */
491 
492 void
494 {
509 
510  /* Set current_target_so_ops to solib_target_so_ops if not already
511  set. */
512  if (current_target_so_ops == 0)
514 }
static const struct gdb_xml_attribute library_list_attributes[]
Definition: solib-target.c:218
static void solib_target_relocate_section_addresses(struct so_list *so, struct target_section *sec)
Definition: solib-target.c:337
static const struct gdb_xml_attribute section_attributes[]
Definition: solib-target.c:191
static void library_list_start_library(struct gdb_xml_parser *parser, const struct gdb_xml_element *element, void *user_data, VEC(gdb_xml_value_s)*attributes)
Definition: solib-target.c:115
CORE_ADDR offsets[1]
Definition: symtab.h:907
bfd_vma CORE_ADDR
Definition: common-types.h:41
void * value
Definition: xml-support.h:76
int gdb_bfd_section_index(bfd *abfd, asection *section)
Definition: gdb_bfd.c:806
void xfree(void *)
Definition: common-utils.c:97
struct so_list * next
Definition: solist.h:36
void warning(const char *fmt,...)
Definition: errors.c:26
CORE_ADDR * segment_bases
Definition: symfile.h:112
initialize_file_ftype _initialize_solib_target
void(* relocate_section_addresses)(struct so_list *so, struct target_section *)
Definition: solist.h:84
void(* solib_create_inferior_hook)(int from_tty)
Definition: solist.h:101
struct so_list *(* current_sos)(void)
Definition: solist.h:116
bfd *(* bfd_open)(char *pathname)
Definition: solist.h:130
Definition: solist.h:30
#define VEC_safe_push(T, V, O)
Definition: vec.h:260
#define SO_NAME_MAX_PATH_SIZE
Definition: solist.h:22
#define _(String)
Definition: gdb_locale.h:40
DEF_VEC_P(lm_info_p)
int(* open_symbol_file_object)(void *from_ttyp)
Definition: solist.h:123
bfd * abfd
Definition: solist.h:63
static const struct gdb_xml_element library_list_children[]
Definition: solib-target.c:211
struct lm_info * lm_info
Definition: solist.h:42
void(* clear_solib)(void)
Definition: solist.h:98
struct target_so_ops solib_target_so_ops
Definition: solib-target.c:487
#define SIZEOF_N_SECTION_OFFSETS(n)
Definition: symtab.h:917
const char *const name
Definition: aarch64-tdep.c:68
#define VEC_iterate(T, V, I, P)
Definition: vec.h:165
int(* in_dynsym_resolve_code)(CORE_ADDR pc)
Definition: solist.h:127
static int solib_target_open_symbol_file_object(void *from_ttyp)
Definition: solib-target.c:471
int gdb_xml_parse_quick(const char *name, const char *dtd_name, const struct gdb_xml_element *elements, const char *document, void *user_data)
Definition: xml-support.c:599
struct target_ops current_target
void initialize_file_ftype(void)
Definition: defs.h:281
static const struct gdb_xml_element library_children[]
Definition: solib-target.c:196
struct symfile_segment_data * get_symfile_segment_data(bfd *abfd)
Definition: symfile.c:3783
void * xzalloc(size_t size)
Definition: common-utils.c:91
static void library_list_end_library(struct gdb_xml_parser *parser, const struct gdb_xml_element *element, void *user_data, const char *body_text)
Definition: solib-target.c:128
static void solib_target_special_symbol_handling(void)
Definition: solib-target.c:310
char so_original_name[SO_NAME_MAX_PATH_SIZE]
Definition: solist.h:49
#define VEC_length(T, V)
Definition: vec.h:124
struct cleanup * make_cleanup(make_cleanup_ftype *function, void *arg)
Definition: cleanups.c:117
const char version[]
Definition: version.c:2
char so_name[SO_NAME_MAX_PATH_SIZE]
Definition: solist.h:52
char * target_read_stralloc(struct target_ops *ops, enum target_object object, const char *annex)
Definition: target.c:1984
#define gdb_assert(expr)
Definition: gdb_assert.h:33
CORE_ADDR endaddr
Definition: target.h:2260
static void solib_target_free_library_list(void *p)
Definition: solib-target.c:166
struct bfd_section * the_bfd_section
Definition: target.h:2262
static void library_list_start_list(struct gdb_xml_parser *parser, const struct gdb_xml_element *element, void *user_data, VEC(gdb_xml_value_s)*attributes)
Definition: solib-target.c:145
void(* special_symbol_handling)(void)
Definition: solist.h:107
CORE_ADDR addr
Definition: target.h:2259
void gdb_xml_error(struct gdb_xml_parser *parser, const char *format,...)
Definition: xml-support.c:128
#define VEC_last(T, V)
Definition: vec.h:142
static const struct gdb_xml_attribute segment_attributes[]
Definition: solib-target.c:186
static void solib_target_free_so(struct so_list *so)
Definition: solib-target.c:328
static void solib_target_clear_solib(void)
Definition: solib-target.c:322
char * name
Definition: solib-target.c:34
CORE_ADDR addr_low
Definition: solist.h:77
struct gdb_xml_value * xml_find_attribute(VEC(gdb_xml_value_s)*attributes, const char *name)
Definition: xml-support.c:142
void discard_cleanups(struct cleanup *old_chain)
Definition: cleanups.c:213
static VEC(lm_info_p)
Definition: solib-target.c:229
static int in_plt_section(CORE_ADDR pc)
Definition: objfiles.h:539
int gdb_bfd_count_sections(bfd *abfd)
Definition: gdb_bfd.c:824
void(* free_so)(struct so_list *so)
Definition: solist.h:89
int offset
Definition: agent.c:65
#define VEC_free(T, V)
Definition: vec.h:180
struct target_so_ops * current_target_so_ops
Definition: solib.c:88
#define VEC_address(T, V)
Definition: vec.h:369
static void library_list_start_section(struct gdb_xml_parser *parser, const struct gdb_xml_element *element, void *user_data, VEC(gdb_xml_value_s)*attributes)
Definition: solib-target.c:96
gdb_xml_attribute_handler gdb_xml_parse_attr_ulongest
unsigned long long ULONGEST
Definition: common-types.h:53
static void solib_target_solib_create_inferior_hook(int from_tty)
Definition: solib-target.c:316
CORE_ADDR addr_high
Definition: solist.h:77
static const struct gdb_xml_attribute library_attributes[]
Definition: solib-target.c:206
void free_symfile_segment_data(struct symfile_segment_data *data)
Definition: symfile.c:3794
struct lm_info * lm_info_p
Definition: solib-target.c:52
static void library_list_start_segment(struct gdb_xml_parser *parser, const struct gdb_xml_element *element, void *user_data, VEC(gdb_xml_value_s)*attributes)
Definition: solib-target.c:79
CORE_ADDR * segment_sizes
Definition: symfile.h:116
int symfile_map_offsets_to_segments(bfd *abfd, const struct symfile_segment_data *data, struct section_offsets *offsets, int num_segment_bases, const CORE_ADDR *segment_bases)
Definition: symfile.c:3818
static int solib_target_in_dynsym_resolve_code(CORE_ADDR pc)
Definition: solib-target.c:479
bfd * solib_bfd_open(char *pathname)
Definition: solib.c:481
static struct so_list * solib_target_current_sos(void)
Definition: solib-target.c:250
void do_cleanups(struct cleanup *old_chain)
Definition: cleanups.c:175