GDB (xrefs)
/tmp/gdb-7.10/gdb/xml-syscall.c
Go to the documentation of this file.
1 /* Functions that provide the mechanism to parse a syscall XML file
2  and get its values.
3 
4  Copyright (C) 2009-2015 Free Software Foundation, Inc.
5 
6  This file is part of GDB.
7 
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 
21 #include "defs.h"
22 #include "gdbtypes.h"
23 #include "xml-support.h"
24 #include "xml-syscall.h"
25 #include "gdbarch.h"
26 
27 /* For the struct syscall definition. */
28 #include "target.h"
29 
30 #include "filenames.h"
31 
32 #ifndef HAVE_LIBEXPAT
33 
34 /* Dummy functions to indicate that there's no support for fetching
35  syscalls information. */
36 
37 static void
38 syscall_warn_user (void)
39 {
40  static int have_warned = 0;
41  if (!have_warned)
42  {
43  have_warned = 1;
44  warning (_("Can not parse XML syscalls information; XML support was "
45  "disabled at compile time."));
46  }
47 }
48 
49 void
50 set_xml_syscall_file_name (struct gdbarch *gdbarch, const char *name)
51 {
52  return;
53 }
54 
55 void
57  int syscall_number, struct syscall *s)
58 {
59  syscall_warn_user ();
60  s->number = syscall_number;
61  s->name = NULL;
62 }
63 
64 void
65 get_syscall_by_name (struct gdbarch *gdbarch, const char *syscall_name,
66  struct syscall *s)
67 {
68  syscall_warn_user ();
70  s->name = syscall_name;
71 }
72 
73 const char **
75 {
76  syscall_warn_user ();
77  return NULL;
78 }
79 
80 #else /* ! HAVE_LIBEXPAT */
81 
82 /* Structure which describes a syscall. */
83 typedef struct syscall_desc
84 {
85  /* The syscall number. */
86 
87  int number;
88 
89  /* The syscall name. */
90 
91  char *name;
94 
95 /* Structure that represents syscalls information. */
97 {
98  /* The syscalls. */
99 
100  VEC(syscall_desc_p) *syscalls;
101 
102  /* Variable that will hold the last known data-directory. This is
103  useful to know whether we should re-read the XML info for the
104  target. */
105 
106  char *my_gdb_datadir;
107 };
108 
109 /* Callback data for syscall information parsing. */
111 {
112  /* The syscalls_info we are building. */
113 
115 };
116 
117 static struct syscalls_info *
119 {
120  return XCNEW (struct syscalls_info);
121 }
122 
123 static void
125 {
126  xfree (sd->name);
127 }
128 
129 static void
131 {
132  struct syscalls_info *syscalls_info = arg;
133  struct syscall_desc *sysdesc;
134  int i;
135 
136  xfree (syscalls_info->my_gdb_datadir);
137 
138  if (syscalls_info->syscalls != NULL)
139  {
140  for (i = 0;
141  VEC_iterate (syscall_desc_p, syscalls_info->syscalls, i, sysdesc);
142  i++)
144  VEC_free (syscall_desc_p, syscalls_info->syscalls);
145  }
146 
147  xfree (syscalls_info);
148 }
149 
150 static struct cleanup *
152 {
153  return make_cleanup (free_syscalls_info, syscalls_info);
154 }
155 
156 static void
158  const char *name, int number)
159 {
160  struct syscall_desc *sysdesc = XCNEW (struct syscall_desc);
161 
162  sysdesc->name = xstrdup (name);
163  sysdesc->number = number;
164 
165  VEC_safe_push (syscall_desc_p, syscalls_info->syscalls, sysdesc);
166 }
167 
168 /* Handle the start of a <syscall> element. */
169 static void
171  const struct gdb_xml_element *element,
172  void *user_data, VEC(gdb_xml_value_s) *attributes)
173 {
174  struct syscall_parsing_data *data = user_data;
175  struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
176  int len, i;
177  /* syscall info. */
178  char *name = NULL;
179  int number = 0;
180 
181  len = VEC_length (gdb_xml_value_s, attributes);
182 
183  for (i = 0; i < len; i++)
184  {
185  if (strcmp (attrs[i].name, "name") == 0)
186  name = attrs[i].value;
187  else if (strcmp (attrs[i].name, "number") == 0)
188  number = * (ULONGEST *) attrs[i].value;
189  else
190  internal_error (__FILE__, __LINE__,
191  _("Unknown attribute name '%s'."), attrs[i].name);
192  }
193 
194  gdb_assert (name);
195  syscall_create_syscall_desc (data->syscalls_info, name, number);
196 }
197 
198 
199 /* The elements and attributes of an XML syscall document. */
200 static const struct gdb_xml_attribute syscall_attr[] = {
201  { "number", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
202  { "name", GDB_XML_AF_NONE, NULL, NULL },
203  { NULL, GDB_XML_AF_NONE, NULL, NULL }
204 };
205 
206 static const struct gdb_xml_element syscalls_info_children[] = {
207  { "syscall", syscall_attr, NULL,
209  syscall_start_syscall, NULL },
210  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
211 };
212 
213 static const struct gdb_xml_element syselements[] = {
214  { "syscalls_info", NULL, syscalls_info_children,
215  GDB_XML_EF_NONE, NULL, NULL },
216  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
217 };
218 
219 static struct syscalls_info *
220 syscall_parse_xml (const char *document, xml_fetch_another fetcher,
221  void *fetcher_baton)
222 {
223  struct cleanup *result_cleanup;
224  struct syscall_parsing_data data;
225 
227  result_cleanup = make_cleanup_free_syscalls_info (data.syscalls_info);
228 
229  if (gdb_xml_parse_quick (_("syscalls info"), NULL,
230  syselements, document, &data) == 0)
231  {
232  /* Parsed successfully. */
233  discard_cleanups (result_cleanup);
234  return data.syscalls_info;
235  }
236  else
237  {
238  warning (_("Could not load XML syscalls info; ignoring"));
239  do_cleanups (result_cleanup);
240  return NULL;
241  }
242 }
243 
244 /* Function responsible for initializing the information
245  about the syscalls. It reads the XML file and fills the
246  struct syscalls_info with the values.
247 
248  Returns the struct syscalls_info if the file is valid, NULL otherwise. */
249 static struct syscalls_info *
250 xml_init_syscalls_info (const char *filename)
251 {
252  char *full_file;
253  char *dirname;
255  struct cleanup *back_to;
256 
257  full_file = xml_fetch_content_from_file (filename, gdb_datadir);
258  if (full_file == NULL)
259  return NULL;
260 
261  back_to = make_cleanup (xfree, full_file);
262 
263  dirname = ldirname (filename);
264  if (dirname != NULL)
265  make_cleanup (xfree, dirname);
266 
267  syscalls_info = syscall_parse_xml (full_file,
268  xml_fetch_content_from_file, dirname);
269  do_cleanups (back_to);
270 
271  return syscalls_info;
272 }
273 
274 /* Initializes the syscalls_info structure according to the
275  architecture. */
276 static void
278 {
280  const char *xml_syscall_file = gdbarch_xml_syscall_file (gdbarch);
281 
282  /* Should we re-read the XML info for this target? */
283  if (syscalls_info != NULL && syscalls_info->my_gdb_datadir != NULL
284  && filename_cmp (syscalls_info->my_gdb_datadir, gdb_datadir) != 0)
285  {
286  /* The data-directory changed from the last time we used it.
287  It means that we have to re-read the XML info. */
288  free_syscalls_info (syscalls_info);
289  syscalls_info = NULL;
290  set_gdbarch_syscalls_info (gdbarch, NULL);
291  }
292 
293  /* Did we succeed at initializing this? */
294  if (syscalls_info != NULL)
295  return;
296 
297  syscalls_info = xml_init_syscalls_info (xml_syscall_file);
298 
299  /* If there was some error reading the XML file, we initialize
300  gdbarch->syscalls_info anyway, in order to store information
301  about our attempt. */
302  if (syscalls_info == NULL)
303  syscalls_info = allocate_syscalls_info ();
304 
305  if (syscalls_info->syscalls == NULL)
306  {
307  if (xml_syscall_file != NULL)
308  warning (_("Could not load the syscall XML file `%s/%s'."),
309  gdb_datadir, xml_syscall_file);
310  else
311  warning (_("There is no XML file to open."));
312 
313  warning (_("GDB will not be able to display "
314  "syscall names nor to verify if\n"
315  "any provided syscall numbers are valid."));
316  }
317 
318  /* Saving the data-directory used to read this XML info. */
319  syscalls_info->my_gdb_datadir = xstrdup (gdb_datadir);
320 
321  set_gdbarch_syscalls_info (gdbarch, syscalls_info);
322 }
323 
324 static int
326  const char *syscall_name)
327 {
329  struct syscall_desc *sysdesc;
330  int i;
331 
332  if (syscalls_info == NULL
333  || syscall_name == NULL)
334  return UNKNOWN_SYSCALL;
335 
336  for (i = 0;
337  VEC_iterate(syscall_desc_p, syscalls_info->syscalls, i, sysdesc);
338  i++)
339  if (strcmp (sysdesc->name, syscall_name) == 0)
340  return sysdesc->number;
341 
342  return UNKNOWN_SYSCALL;
343 }
344 
345 static const char *
347  int syscall_number)
348 {
350  struct syscall_desc *sysdesc;
351  int i;
352 
353  if (syscalls_info == NULL
354  || syscall_number < 0)
355  return NULL;
356 
357  for (i = 0;
358  VEC_iterate(syscall_desc_p, syscalls_info->syscalls, i, sysdesc);
359  i++)
360  if (sysdesc->number == syscall_number)
361  return sysdesc->name;
362 
363  return NULL;
364 }
365 
366 static const char **
368 {
370  struct syscall_desc *sysdesc;
371  const char **names = NULL;
372  int nsyscalls;
373  int i;
374 
375  if (syscalls_info == NULL)
376  return NULL;
377 
378  nsyscalls = VEC_length (syscall_desc_p, syscalls_info->syscalls);
379  names = xmalloc ((nsyscalls + 1) * sizeof (char *));
380 
381  for (i = 0;
382  VEC_iterate (syscall_desc_p, syscalls_info->syscalls, i, sysdesc);
383  i++)
384  names[i] = sysdesc->name;
385 
386  names[i] = NULL;
387 
388  return names;
389 }
390 
391 void
393 {
394  set_gdbarch_xml_syscall_file (gdbarch, name);
395 }
396 
397 void
399  int syscall_number, struct syscall *s)
400 {
401  init_syscalls_info (gdbarch);
402 
403  s->number = syscall_number;
404  s->name = xml_get_syscall_name (gdbarch, syscall_number);
405 }
406 
407 void
409  const char *syscall_name, struct syscall *s)
410 {
411  init_syscalls_info (gdbarch);
412 
413  s->number = xml_get_syscall_number (gdbarch, syscall_name);
414  s->name = syscall_name;
415 }
416 
417 const char **
419 {
420  init_syscalls_info (gdbarch);
421 
422  return xml_list_of_syscalls (gdbarch);
423 }
424 
425 #endif /* ! HAVE_LIBEXPAT */
static void syscall_create_syscall_desc(struct syscalls_info *syscalls_info, const char *name, int number)
Definition: xml-syscall.c:157
static const struct gdb_xml_attribute syscall_attr[]
Definition: xml-syscall.c:200
static void syscalls_info_free_syscalls_desc(struct syscall_desc *sd)
Definition: xml-syscall.c:124
Definition: target.h:98
void * value
Definition: xml-support.h:76
char *(* xml_fetch_another)(const char *href, void *baton)
Definition: xml-support.h:55
void xfree(void *)
Definition: common-utils.c:97
void warning(const char *fmt,...)
Definition: errors.c:26
char * ldirname(const char *filename)
Definition: utils.c:3006
void internal_error(const char *file, int line, const char *fmt,...)
Definition: errors.c:50
static struct syscalls_info * syscall_parse_xml(const char *document, xml_fetch_another fetcher, void *fetcher_baton)
Definition: xml-syscall.c:220
#define VEC_safe_push(T, V, O)
Definition: vec.h:260
struct syscalls_info * syscalls_info
Definition: xml-syscall.c:114
#define VEC(T)
Definition: vec.h:398
static void free_syscalls_info(void *arg)
Definition: xml-syscall.c:130
void get_syscall_by_name(struct gdbarch *gdbarch, const char *syscall_name, struct syscall *s)
Definition: xml-syscall.c:408
#define _(String)
Definition: gdb_locale.h:40
void set_gdbarch_syscalls_info(struct gdbarch *gdbarch, struct syscalls_info *syscalls_info)
Definition: gdbarch.c:4059
static struct cleanup * make_cleanup_free_syscalls_info(struct syscalls_info *syscalls_info)
Definition: xml-syscall.c:151
struct syscall_desc * syscall_desc_p
void get_syscall_by_number(struct gdbarch *gdbarch, int syscall_number, struct syscall *s)
Definition: xml-syscall.c:398
const char *const name
Definition: aarch64-tdep.c:68
int number
Definition: target.h:101
#define VEC_iterate(T, V, I, P)
Definition: vec.h:165
static struct syscalls_info * xml_init_syscalls_info(const char *filename)
Definition: xml-syscall.c:250
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
static struct syscalls_info * allocate_syscalls_info(void)
Definition: xml-syscall.c:118
#define VEC_length(T, V)
Definition: vec.h:124
struct cleanup * make_cleanup(make_cleanup_ftype *function, void *arg)
Definition: cleanups.c:117
static const char ** xml_list_of_syscalls(struct gdbarch *gdbarch)
Definition: xml-syscall.c:367
char * gdb_datadir
Definition: main.c:60
#define gdb_assert(expr)
Definition: gdb_assert.h:33
#define UNKNOWN_SYSCALL
Definition: gdbarch.h:1478
char * xml_fetch_content_from_file(const char *filename, void *baton)
Definition: xml-support.c:1016
void set_xml_syscall_file_name(struct gdbarch *gdbarch, const char *name)
Definition: xml-syscall.c:392
void * xmalloc(YYSIZE_T)
const char * gdbarch_xml_syscall_file(struct gdbarch *gdbarch)
Definition: gdbarch.c:4032
Definition: value.c:172
const char ** get_syscall_names(struct gdbarch *gdbarch)
Definition: xml-syscall.c:418
void discard_cleanups(struct cleanup *old_chain)
Definition: cleanups.c:213
static const char * xml_get_syscall_name(struct gdbarch *gdbarch, int syscall_number)
Definition: xml-syscall.c:346
static int xml_get_syscall_number(struct gdbarch *gdbarch, const char *syscall_name)
Definition: xml-syscall.c:325
#define VEC_free(T, V)
Definition: vec.h:180
#define VEC_address(T, V)
Definition: vec.h:369
gdb_xml_attribute_handler gdb_xml_parse_attr_ulongest
unsigned long long ULONGEST
Definition: common-types.h:53
static const struct gdb_xml_element syscalls_info_children[]
Definition: xml-syscall.c:206
void set_gdbarch_xml_syscall_file(struct gdbarch *gdbarch, const char *xml_syscall_file)
Definition: gdbarch.c:4042
static void init_syscalls_info(struct gdbarch *gdbarch)
Definition: xml-syscall.c:277
const char * name
Definition: target.h:104
static void syscall_start_syscall(struct gdb_xml_parser *parser, const struct gdb_xml_element *element, void *user_data, VEC(gdb_xml_value_s)*attributes)
Definition: xml-syscall.c:170
struct syscalls_info * gdbarch_syscalls_info(struct gdbarch *gdbarch)
Definition: gdbarch.c:4049
void do_cleanups(struct cleanup *old_chain)
Definition: cleanups.c:175
char * name
Definition: xml-syscall.c:91
DEF_VEC_P(syscall_desc_p)
const ULONGEST const LONGEST len
Definition: target.h:309