xml-syscall.c revision 1.6 1 1.1 christos /* Functions that provide the mechanism to parse a syscall XML file
2 1.1 christos and get its values.
3 1.1 christos
4 1.6 christos Copyright (C) 2009-2016 Free Software Foundation, Inc.
5 1.1 christos
6 1.1 christos This file is part of GDB.
7 1.1 christos
8 1.1 christos This program is free software; you can redistribute it and/or modify
9 1.1 christos it under the terms of the GNU General Public License as published by
10 1.1 christos the Free Software Foundation; either version 3 of the License, or
11 1.1 christos (at your option) any later version.
12 1.1 christos
13 1.1 christos This program is distributed in the hope that it will be useful,
14 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
15 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 1.1 christos GNU General Public License for more details.
17 1.1 christos
18 1.1 christos You should have received a copy of the GNU General Public License
19 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 1.1 christos
21 1.1 christos #include "defs.h"
22 1.1 christos #include "gdbtypes.h"
23 1.1 christos #include "xml-support.h"
24 1.1 christos #include "xml-syscall.h"
25 1.3 christos #include "gdbarch.h"
26 1.1 christos
27 1.1 christos /* For the struct syscall definition. */
28 1.1 christos #include "target.h"
29 1.1 christos
30 1.1 christos #include "filenames.h"
31 1.1 christos
32 1.1 christos #ifndef HAVE_LIBEXPAT
33 1.1 christos
34 1.1 christos /* Dummy functions to indicate that there's no support for fetching
35 1.1 christos syscalls information. */
36 1.1 christos
37 1.1 christos static void
38 1.1 christos syscall_warn_user (void)
39 1.1 christos {
40 1.1 christos static int have_warned = 0;
41 1.1 christos if (!have_warned)
42 1.1 christos {
43 1.1 christos have_warned = 1;
44 1.1 christos warning (_("Can not parse XML syscalls information; XML support was "
45 1.1 christos "disabled at compile time."));
46 1.1 christos }
47 1.1 christos }
48 1.1 christos
49 1.1 christos void
50 1.3 christos set_xml_syscall_file_name (struct gdbarch *gdbarch, const char *name)
51 1.1 christos {
52 1.1 christos return;
53 1.1 christos }
54 1.1 christos
55 1.1 christos void
56 1.3 christos get_syscall_by_number (struct gdbarch *gdbarch,
57 1.3 christos int syscall_number, struct syscall *s)
58 1.1 christos {
59 1.1 christos syscall_warn_user ();
60 1.1 christos s->number = syscall_number;
61 1.1 christos s->name = NULL;
62 1.1 christos }
63 1.1 christos
64 1.1 christos void
65 1.3 christos get_syscall_by_name (struct gdbarch *gdbarch, const char *syscall_name,
66 1.3 christos struct syscall *s)
67 1.1 christos {
68 1.1 christos syscall_warn_user ();
69 1.1 christos s->number = UNKNOWN_SYSCALL;
70 1.1 christos s->name = syscall_name;
71 1.1 christos }
72 1.1 christos
73 1.1 christos const char **
74 1.3 christos get_syscall_names (struct gdbarch *gdbarch)
75 1.1 christos {
76 1.1 christos syscall_warn_user ();
77 1.1 christos return NULL;
78 1.1 christos }
79 1.1 christos
80 1.6 christos struct syscall *
81 1.6 christos get_syscalls_by_group (struct gdbarch *gdbarch, const char *group)
82 1.6 christos {
83 1.6 christos syscall_warn_user ();
84 1.6 christos return NULL;
85 1.6 christos }
86 1.6 christos
87 1.6 christos const char **
88 1.6 christos get_syscall_group_names (struct gdbarch *gdbarch)
89 1.6 christos {
90 1.6 christos syscall_warn_user ();
91 1.6 christos return NULL;
92 1.6 christos }
93 1.6 christos
94 1.1 christos #else /* ! HAVE_LIBEXPAT */
95 1.1 christos
96 1.1 christos /* Structure which describes a syscall. */
97 1.1 christos typedef struct syscall_desc
98 1.1 christos {
99 1.1 christos /* The syscall number. */
100 1.1 christos
101 1.1 christos int number;
102 1.1 christos
103 1.1 christos /* The syscall name. */
104 1.1 christos
105 1.1 christos char *name;
106 1.1 christos } *syscall_desc_p;
107 1.1 christos DEF_VEC_P(syscall_desc_p);
108 1.1 christos
109 1.6 christos /* Structure of a syscall group. */
110 1.6 christos typedef struct syscall_group_desc
111 1.6 christos {
112 1.6 christos /* The group name. */
113 1.6 christos
114 1.6 christos char *name;
115 1.6 christos
116 1.6 christos /* The syscalls that are part of the group. */
117 1.6 christos
118 1.6 christos VEC(syscall_desc_p) *syscalls;
119 1.6 christos } *syscall_group_desc_p;
120 1.6 christos DEF_VEC_P(syscall_group_desc_p);
121 1.6 christos
122 1.1 christos /* Structure that represents syscalls information. */
123 1.1 christos struct syscalls_info
124 1.1 christos {
125 1.1 christos /* The syscalls. */
126 1.1 christos
127 1.1 christos VEC(syscall_desc_p) *syscalls;
128 1.3 christos
129 1.6 christos /* The syscall groups. */
130 1.6 christos
131 1.6 christos VEC(syscall_group_desc_p) *groups;
132 1.6 christos
133 1.3 christos /* Variable that will hold the last known data-directory. This is
134 1.3 christos useful to know whether we should re-read the XML info for the
135 1.3 christos target. */
136 1.3 christos
137 1.3 christos char *my_gdb_datadir;
138 1.1 christos };
139 1.1 christos
140 1.1 christos /* Callback data for syscall information parsing. */
141 1.1 christos struct syscall_parsing_data
142 1.1 christos {
143 1.1 christos /* The syscalls_info we are building. */
144 1.1 christos
145 1.3 christos struct syscalls_info *syscalls_info;
146 1.1 christos };
147 1.1 christos
148 1.1 christos static struct syscalls_info *
149 1.1 christos allocate_syscalls_info (void)
150 1.1 christos {
151 1.3 christos return XCNEW (struct syscalls_info);
152 1.1 christos }
153 1.1 christos
154 1.1 christos static void
155 1.3 christos syscalls_info_free_syscalls_desc (struct syscall_desc *sd)
156 1.1 christos {
157 1.1 christos xfree (sd->name);
158 1.1 christos }
159 1.1 christos
160 1.6 christos /* Free syscall_group_desc members but not the structure itself. */
161 1.6 christos
162 1.6 christos static void
163 1.6 christos syscalls_info_free_syscall_group_desc (struct syscall_group_desc *sd)
164 1.6 christos {
165 1.6 christos VEC_free (syscall_desc_p, sd->syscalls);
166 1.6 christos xfree (sd->name);
167 1.6 christos }
168 1.6 christos
169 1.1 christos static void
170 1.1 christos free_syscalls_info (void *arg)
171 1.1 christos {
172 1.6 christos struct syscalls_info *syscalls_info = (struct syscalls_info *) arg;
173 1.1 christos struct syscall_desc *sysdesc;
174 1.6 christos struct syscall_group_desc *groupdesc;
175 1.1 christos int i;
176 1.1 christos
177 1.3 christos xfree (syscalls_info->my_gdb_datadir);
178 1.3 christos
179 1.3 christos if (syscalls_info->syscalls != NULL)
180 1.3 christos {
181 1.3 christos for (i = 0;
182 1.3 christos VEC_iterate (syscall_desc_p, syscalls_info->syscalls, i, sysdesc);
183 1.3 christos i++)
184 1.3 christos syscalls_info_free_syscalls_desc (sysdesc);
185 1.3 christos VEC_free (syscall_desc_p, syscalls_info->syscalls);
186 1.3 christos }
187 1.1 christos
188 1.6 christos if (syscalls_info->groups != NULL)
189 1.6 christos {
190 1.6 christos for (i = 0;
191 1.6 christos VEC_iterate (syscall_group_desc_p,
192 1.6 christos syscalls_info->groups, i, groupdesc);
193 1.6 christos i++)
194 1.6 christos syscalls_info_free_syscall_group_desc (groupdesc);
195 1.6 christos
196 1.6 christos VEC_free (syscall_group_desc_p, syscalls_info->groups);
197 1.6 christos }
198 1.6 christos
199 1.3 christos xfree (syscalls_info);
200 1.1 christos }
201 1.1 christos
202 1.1 christos static struct cleanup *
203 1.3 christos make_cleanup_free_syscalls_info (struct syscalls_info *syscalls_info)
204 1.1 christos {
205 1.3 christos return make_cleanup (free_syscalls_info, syscalls_info);
206 1.1 christos }
207 1.1 christos
208 1.6 christos /* Create a new syscall group. Return pointer to the
209 1.6 christos syscall_group_desc structure that represents the new group. */
210 1.6 christos
211 1.6 christos static struct syscall_group_desc *
212 1.6 christos syscall_group_create_syscall_group_desc (struct syscalls_info *syscalls_info,
213 1.6 christos const char *group)
214 1.6 christos {
215 1.6 christos struct syscall_group_desc *groupdesc = XCNEW (struct syscall_group_desc);
216 1.6 christos
217 1.6 christos groupdesc->name = xstrdup (group);
218 1.6 christos
219 1.6 christos VEC_safe_push (syscall_group_desc_p, syscalls_info->groups, groupdesc);
220 1.6 christos
221 1.6 christos return groupdesc;
222 1.6 christos }
223 1.6 christos
224 1.6 christos /* Add a syscall to the group. If group doesn't exist, create it. */
225 1.6 christos
226 1.6 christos static void
227 1.6 christos syscall_group_add_syscall (struct syscalls_info *syscalls_info,
228 1.6 christos struct syscall_desc *syscall,
229 1.6 christos const char *group)
230 1.6 christos {
231 1.6 christos struct syscall_group_desc *groupdesc = NULL;
232 1.6 christos int i;
233 1.6 christos
234 1.6 christos /* Search for an existing group. */
235 1.6 christos for (i = 0;
236 1.6 christos VEC_iterate (syscall_group_desc_p, syscalls_info->groups, i, groupdesc);
237 1.6 christos i++)
238 1.6 christos {
239 1.6 christos if (strcmp (groupdesc->name, group) == 0)
240 1.6 christos break;
241 1.6 christos }
242 1.6 christos
243 1.6 christos if (groupdesc == NULL)
244 1.6 christos {
245 1.6 christos /* No group was found with this name. We must create a new
246 1.6 christos one. */
247 1.6 christos groupdesc = syscall_group_create_syscall_group_desc (syscalls_info,
248 1.6 christos group);
249 1.6 christos }
250 1.6 christos
251 1.6 christos VEC_safe_push (syscall_desc_p, groupdesc->syscalls, syscall);
252 1.6 christos }
253 1.6 christos
254 1.1 christos static void
255 1.3 christos syscall_create_syscall_desc (struct syscalls_info *syscalls_info,
256 1.6 christos const char *name, int number,
257 1.6 christos char *groups)
258 1.1 christos {
259 1.3 christos struct syscall_desc *sysdesc = XCNEW (struct syscall_desc);
260 1.6 christos char *group;
261 1.1 christos
262 1.1 christos sysdesc->name = xstrdup (name);
263 1.1 christos sysdesc->number = number;
264 1.1 christos
265 1.3 christos VEC_safe_push (syscall_desc_p, syscalls_info->syscalls, sysdesc);
266 1.6 christos
267 1.6 christos /* Add syscall to its groups. */
268 1.6 christos if (groups != NULL)
269 1.6 christos {
270 1.6 christos for (group = strtok (groups, ",");
271 1.6 christos group != NULL;
272 1.6 christos group = strtok (NULL, ","))
273 1.6 christos syscall_group_add_syscall (syscalls_info, sysdesc, group);
274 1.6 christos }
275 1.1 christos }
276 1.1 christos
277 1.1 christos /* Handle the start of a <syscall> element. */
278 1.1 christos static void
279 1.1 christos syscall_start_syscall (struct gdb_xml_parser *parser,
280 1.1 christos const struct gdb_xml_element *element,
281 1.1 christos void *user_data, VEC(gdb_xml_value_s) *attributes)
282 1.1 christos {
283 1.6 christos struct syscall_parsing_data *data = (struct syscall_parsing_data *) user_data;
284 1.1 christos struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
285 1.1 christos int len, i;
286 1.1 christos /* syscall info. */
287 1.1 christos char *name = NULL;
288 1.1 christos int number = 0;
289 1.6 christos char *groups = NULL;
290 1.1 christos
291 1.1 christos len = VEC_length (gdb_xml_value_s, attributes);
292 1.1 christos
293 1.1 christos for (i = 0; i < len; i++)
294 1.1 christos {
295 1.1 christos if (strcmp (attrs[i].name, "name") == 0)
296 1.6 christos name = (char *) attrs[i].value;
297 1.1 christos else if (strcmp (attrs[i].name, "number") == 0)
298 1.1 christos number = * (ULONGEST *) attrs[i].value;
299 1.6 christos else if (strcmp (attrs[i].name, "groups") == 0)
300 1.6 christos groups = (char *) attrs[i].value;
301 1.1 christos else
302 1.1 christos internal_error (__FILE__, __LINE__,
303 1.1 christos _("Unknown attribute name '%s'."), attrs[i].name);
304 1.1 christos }
305 1.1 christos
306 1.1 christos gdb_assert (name);
307 1.6 christos syscall_create_syscall_desc (data->syscalls_info, name, number, groups);
308 1.1 christos }
309 1.1 christos
310 1.1 christos
311 1.1 christos /* The elements and attributes of an XML syscall document. */
312 1.1 christos static const struct gdb_xml_attribute syscall_attr[] = {
313 1.1 christos { "number", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
314 1.1 christos { "name", GDB_XML_AF_NONE, NULL, NULL },
315 1.6 christos { "groups", GDB_XML_AF_OPTIONAL, NULL, NULL },
316 1.1 christos { NULL, GDB_XML_AF_NONE, NULL, NULL }
317 1.1 christos };
318 1.1 christos
319 1.1 christos static const struct gdb_xml_element syscalls_info_children[] = {
320 1.1 christos { "syscall", syscall_attr, NULL,
321 1.1 christos GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
322 1.1 christos syscall_start_syscall, NULL },
323 1.1 christos { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
324 1.1 christos };
325 1.1 christos
326 1.1 christos static const struct gdb_xml_element syselements[] = {
327 1.1 christos { "syscalls_info", NULL, syscalls_info_children,
328 1.1 christos GDB_XML_EF_NONE, NULL, NULL },
329 1.1 christos { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
330 1.1 christos };
331 1.1 christos
332 1.1 christos static struct syscalls_info *
333 1.1 christos syscall_parse_xml (const char *document, xml_fetch_another fetcher,
334 1.1 christos void *fetcher_baton)
335 1.1 christos {
336 1.1 christos struct cleanup *result_cleanup;
337 1.1 christos struct syscall_parsing_data data;
338 1.1 christos
339 1.3 christos data.syscalls_info = allocate_syscalls_info ();
340 1.3 christos result_cleanup = make_cleanup_free_syscalls_info (data.syscalls_info);
341 1.1 christos
342 1.1 christos if (gdb_xml_parse_quick (_("syscalls info"), NULL,
343 1.1 christos syselements, document, &data) == 0)
344 1.1 christos {
345 1.1 christos /* Parsed successfully. */
346 1.1 christos discard_cleanups (result_cleanup);
347 1.3 christos return data.syscalls_info;
348 1.1 christos }
349 1.1 christos else
350 1.1 christos {
351 1.1 christos warning (_("Could not load XML syscalls info; ignoring"));
352 1.1 christos do_cleanups (result_cleanup);
353 1.1 christos return NULL;
354 1.1 christos }
355 1.1 christos }
356 1.1 christos
357 1.1 christos /* Function responsible for initializing the information
358 1.1 christos about the syscalls. It reads the XML file and fills the
359 1.1 christos struct syscalls_info with the values.
360 1.1 christos
361 1.1 christos Returns the struct syscalls_info if the file is valid, NULL otherwise. */
362 1.3 christos static struct syscalls_info *
363 1.1 christos xml_init_syscalls_info (const char *filename)
364 1.1 christos {
365 1.1 christos char *full_file;
366 1.1 christos char *dirname;
367 1.3 christos struct syscalls_info *syscalls_info;
368 1.1 christos struct cleanup *back_to;
369 1.1 christos
370 1.1 christos full_file = xml_fetch_content_from_file (filename, gdb_datadir);
371 1.1 christos if (full_file == NULL)
372 1.1 christos return NULL;
373 1.1 christos
374 1.1 christos back_to = make_cleanup (xfree, full_file);
375 1.1 christos
376 1.1 christos dirname = ldirname (filename);
377 1.1 christos if (dirname != NULL)
378 1.1 christos make_cleanup (xfree, dirname);
379 1.1 christos
380 1.3 christos syscalls_info = syscall_parse_xml (full_file,
381 1.3 christos xml_fetch_content_from_file, dirname);
382 1.1 christos do_cleanups (back_to);
383 1.1 christos
384 1.3 christos return syscalls_info;
385 1.1 christos }
386 1.1 christos
387 1.1 christos /* Initializes the syscalls_info structure according to the
388 1.1 christos architecture. */
389 1.1 christos static void
390 1.3 christos init_syscalls_info (struct gdbarch *gdbarch)
391 1.1 christos {
392 1.3 christos struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch);
393 1.3 christos const char *xml_syscall_file = gdbarch_xml_syscall_file (gdbarch);
394 1.3 christos
395 1.1 christos /* Should we re-read the XML info for this target? */
396 1.3 christos if (syscalls_info != NULL && syscalls_info->my_gdb_datadir != NULL
397 1.3 christos && filename_cmp (syscalls_info->my_gdb_datadir, gdb_datadir) != 0)
398 1.1 christos {
399 1.1 christos /* The data-directory changed from the last time we used it.
400 1.1 christos It means that we have to re-read the XML info. */
401 1.3 christos free_syscalls_info (syscalls_info);
402 1.3 christos syscalls_info = NULL;
403 1.3 christos set_gdbarch_syscalls_info (gdbarch, NULL);
404 1.1 christos }
405 1.1 christos
406 1.3 christos /* Did we succeed at initializing this? */
407 1.3 christos if (syscalls_info != NULL)
408 1.1 christos return;
409 1.1 christos
410 1.3 christos syscalls_info = xml_init_syscalls_info (xml_syscall_file);
411 1.1 christos
412 1.3 christos /* If there was some error reading the XML file, we initialize
413 1.3 christos gdbarch->syscalls_info anyway, in order to store information
414 1.3 christos about our attempt. */
415 1.3 christos if (syscalls_info == NULL)
416 1.3 christos syscalls_info = allocate_syscalls_info ();
417 1.1 christos
418 1.3 christos if (syscalls_info->syscalls == NULL)
419 1.1 christos {
420 1.3 christos if (xml_syscall_file != NULL)
421 1.1 christos warning (_("Could not load the syscall XML file `%s/%s'."),
422 1.1 christos gdb_datadir, xml_syscall_file);
423 1.1 christos else
424 1.1 christos warning (_("There is no XML file to open."));
425 1.1 christos
426 1.1 christos warning (_("GDB will not be able to display "
427 1.1 christos "syscall names nor to verify if\n"
428 1.1 christos "any provided syscall numbers are valid."));
429 1.1 christos }
430 1.1 christos
431 1.1 christos /* Saving the data-directory used to read this XML info. */
432 1.3 christos syscalls_info->my_gdb_datadir = xstrdup (gdb_datadir);
433 1.3 christos
434 1.3 christos set_gdbarch_syscalls_info (gdbarch, syscalls_info);
435 1.1 christos }
436 1.1 christos
437 1.6 christos /* Search for a syscall group by its name. Return syscall_group_desc
438 1.6 christos structure for the group if found or NULL otherwise. */
439 1.6 christos
440 1.6 christos static struct syscall_group_desc *
441 1.6 christos syscall_group_get_group_by_name (const struct syscalls_info *syscalls_info,
442 1.6 christos const char *group)
443 1.6 christos {
444 1.6 christos struct syscall_group_desc *groupdesc;
445 1.6 christos int i;
446 1.6 christos
447 1.6 christos if (syscalls_info == NULL)
448 1.6 christos return NULL;
449 1.6 christos
450 1.6 christos if (group == NULL)
451 1.6 christos return NULL;
452 1.6 christos
453 1.6 christos /* Search for existing group. */
454 1.6 christos for (i = 0;
455 1.6 christos VEC_iterate (syscall_group_desc_p, syscalls_info->groups, i, groupdesc);
456 1.6 christos i++)
457 1.6 christos {
458 1.6 christos if (strcmp (groupdesc->name, group) == 0)
459 1.6 christos return groupdesc;
460 1.6 christos }
461 1.6 christos
462 1.6 christos return NULL;
463 1.6 christos }
464 1.6 christos
465 1.1 christos static int
466 1.3 christos xml_get_syscall_number (struct gdbarch *gdbarch,
467 1.1 christos const char *syscall_name)
468 1.1 christos {
469 1.3 christos struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch);
470 1.1 christos struct syscall_desc *sysdesc;
471 1.1 christos int i;
472 1.1 christos
473 1.3 christos if (syscalls_info == NULL
474 1.1 christos || syscall_name == NULL)
475 1.1 christos return UNKNOWN_SYSCALL;
476 1.1 christos
477 1.1 christos for (i = 0;
478 1.3 christos VEC_iterate(syscall_desc_p, syscalls_info->syscalls, i, sysdesc);
479 1.1 christos i++)
480 1.1 christos if (strcmp (sysdesc->name, syscall_name) == 0)
481 1.1 christos return sysdesc->number;
482 1.1 christos
483 1.1 christos return UNKNOWN_SYSCALL;
484 1.1 christos }
485 1.1 christos
486 1.1 christos static const char *
487 1.3 christos xml_get_syscall_name (struct gdbarch *gdbarch,
488 1.1 christos int syscall_number)
489 1.1 christos {
490 1.3 christos struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch);
491 1.1 christos struct syscall_desc *sysdesc;
492 1.1 christos int i;
493 1.1 christos
494 1.3 christos if (syscalls_info == NULL
495 1.1 christos || syscall_number < 0)
496 1.1 christos return NULL;
497 1.1 christos
498 1.1 christos for (i = 0;
499 1.3 christos VEC_iterate(syscall_desc_p, syscalls_info->syscalls, i, sysdesc);
500 1.1 christos i++)
501 1.1 christos if (sysdesc->number == syscall_number)
502 1.1 christos return sysdesc->name;
503 1.1 christos
504 1.1 christos return NULL;
505 1.1 christos }
506 1.1 christos
507 1.1 christos static const char **
508 1.3 christos xml_list_of_syscalls (struct gdbarch *gdbarch)
509 1.1 christos {
510 1.3 christos struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch);
511 1.1 christos struct syscall_desc *sysdesc;
512 1.1 christos const char **names = NULL;
513 1.1 christos int nsyscalls;
514 1.1 christos int i;
515 1.1 christos
516 1.3 christos if (syscalls_info == NULL)
517 1.1 christos return NULL;
518 1.1 christos
519 1.3 christos nsyscalls = VEC_length (syscall_desc_p, syscalls_info->syscalls);
520 1.6 christos names = XNEWVEC (const char *, nsyscalls + 1);
521 1.1 christos
522 1.1 christos for (i = 0;
523 1.3 christos VEC_iterate (syscall_desc_p, syscalls_info->syscalls, i, sysdesc);
524 1.1 christos i++)
525 1.1 christos names[i] = sysdesc->name;
526 1.1 christos
527 1.1 christos names[i] = NULL;
528 1.1 christos
529 1.1 christos return names;
530 1.1 christos }
531 1.1 christos
532 1.6 christos /* Iterate over the syscall_group_desc element to return a list of
533 1.6 christos syscalls that are part of the given group, terminated by an empty
534 1.6 christos element. If the syscall group doesn't exist, return NULL. */
535 1.6 christos
536 1.6 christos static struct syscall *
537 1.6 christos xml_list_syscalls_by_group (struct gdbarch *gdbarch, const char *group)
538 1.6 christos {
539 1.6 christos struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch);
540 1.6 christos struct syscall_group_desc *groupdesc;
541 1.6 christos struct syscall_desc *sysdesc;
542 1.6 christos struct syscall *syscalls = NULL;
543 1.6 christos int nsyscalls;
544 1.6 christos int i;
545 1.6 christos
546 1.6 christos if (syscalls_info == NULL)
547 1.6 christos return NULL;
548 1.6 christos
549 1.6 christos groupdesc = syscall_group_get_group_by_name (syscalls_info, group);
550 1.6 christos if (groupdesc == NULL)
551 1.6 christos return NULL;
552 1.6 christos
553 1.6 christos nsyscalls = VEC_length (syscall_desc_p, groupdesc->syscalls);
554 1.6 christos syscalls = (struct syscall*) xmalloc ((nsyscalls + 1)
555 1.6 christos * sizeof (struct syscall));
556 1.6 christos
557 1.6 christos for (i = 0;
558 1.6 christos VEC_iterate (syscall_desc_p, groupdesc->syscalls, i, sysdesc);
559 1.6 christos i++)
560 1.6 christos {
561 1.6 christos syscalls[i].name = sysdesc->name;
562 1.6 christos syscalls[i].number = sysdesc->number;
563 1.6 christos }
564 1.6 christos
565 1.6 christos /* Add final element marker. */
566 1.6 christos syscalls[i].name = NULL;
567 1.6 christos syscalls[i].number = 0;
568 1.6 christos
569 1.6 christos return syscalls;
570 1.6 christos }
571 1.6 christos
572 1.6 christos /* Return a NULL terminated list of syscall groups or an empty list, if
573 1.6 christos no syscall group is available. Return NULL, if there is no syscall
574 1.6 christos information available. */
575 1.6 christos
576 1.6 christos static const char **
577 1.6 christos xml_list_of_groups (struct gdbarch *gdbarch)
578 1.6 christos {
579 1.6 christos struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch);
580 1.6 christos struct syscall_group_desc *groupdesc;
581 1.6 christos const char **names = NULL;
582 1.6 christos int i;
583 1.6 christos int ngroups;
584 1.6 christos
585 1.6 christos if (syscalls_info == NULL)
586 1.6 christos return NULL;
587 1.6 christos
588 1.6 christos ngroups = VEC_length (syscall_group_desc_p, syscalls_info->groups);
589 1.6 christos names = (const char**) xmalloc ((ngroups + 1) * sizeof (char *));
590 1.6 christos
591 1.6 christos for (i = 0;
592 1.6 christos VEC_iterate (syscall_group_desc_p, syscalls_info->groups, i, groupdesc);
593 1.6 christos i++)
594 1.6 christos names[i] = groupdesc->name;
595 1.6 christos
596 1.6 christos names[i] = NULL;
597 1.6 christos
598 1.6 christos return names;
599 1.6 christos }
600 1.6 christos
601 1.1 christos void
602 1.3 christos set_xml_syscall_file_name (struct gdbarch *gdbarch, const char *name)
603 1.1 christos {
604 1.3 christos set_gdbarch_xml_syscall_file (gdbarch, name);
605 1.1 christos }
606 1.1 christos
607 1.1 christos void
608 1.3 christos get_syscall_by_number (struct gdbarch *gdbarch,
609 1.3 christos int syscall_number, struct syscall *s)
610 1.1 christos {
611 1.3 christos init_syscalls_info (gdbarch);
612 1.1 christos
613 1.1 christos s->number = syscall_number;
614 1.3 christos s->name = xml_get_syscall_name (gdbarch, syscall_number);
615 1.1 christos }
616 1.1 christos
617 1.1 christos void
618 1.3 christos get_syscall_by_name (struct gdbarch *gdbarch,
619 1.3 christos const char *syscall_name, struct syscall *s)
620 1.1 christos {
621 1.3 christos init_syscalls_info (gdbarch);
622 1.1 christos
623 1.3 christos s->number = xml_get_syscall_number (gdbarch, syscall_name);
624 1.1 christos s->name = syscall_name;
625 1.1 christos }
626 1.1 christos
627 1.1 christos const char **
628 1.3 christos get_syscall_names (struct gdbarch *gdbarch)
629 1.1 christos {
630 1.3 christos init_syscalls_info (gdbarch);
631 1.1 christos
632 1.3 christos return xml_list_of_syscalls (gdbarch);
633 1.1 christos }
634 1.1 christos
635 1.6 christos /* See comment in xml-syscall.h. */
636 1.6 christos
637 1.6 christos struct syscall *
638 1.6 christos get_syscalls_by_group (struct gdbarch *gdbarch, const char *group)
639 1.6 christos {
640 1.6 christos init_syscalls_info (gdbarch);
641 1.6 christos
642 1.6 christos return xml_list_syscalls_by_group (gdbarch, group);
643 1.6 christos }
644 1.6 christos
645 1.6 christos /* See comment in xml-syscall.h. */
646 1.6 christos
647 1.6 christos const char **
648 1.6 christos get_syscall_group_names (struct gdbarch *gdbarch)
649 1.6 christos {
650 1.6 christos init_syscalls_info (gdbarch);
651 1.6 christos
652 1.6 christos return xml_list_of_groups (gdbarch);
653 1.6 christos }
654 1.6 christos
655 1.1 christos #endif /* ! HAVE_LIBEXPAT */
656