OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [gdb/] [xml-syscall.c] - Blame information for rev 227

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* Functions that provide the mechanism to parse a syscall XML file
2
   and get its values.
3
 
4
   Copyright (C) 2009, 2010 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
 
26
/* For the struct syscall definition.  */
27
#include "target.h"
28
 
29
#include "filenames.h"
30
 
31
#include "gdb_assert.h"
32
 
33
#ifndef HAVE_LIBEXPAT
34
 
35
/* Dummy functions to indicate that there's no support for fetching
36
   syscalls information.  */
37
 
38
static void
39
syscall_warn_user (void)
40
{
41
  static int have_warned = 0;
42
  if (!have_warned)
43
    {
44
      have_warned = 1;
45
      warning (_("Can not parse XML syscalls information; XML support was "
46
                 "disabled at compile time."));
47
    }
48
}
49
 
50
void
51
set_xml_syscall_file_name (const char *name)
52
{
53
  return;
54
}
55
 
56
void
57
get_syscall_by_number (int syscall_number,
58
                       struct syscall *s)
59
{
60
  syscall_warn_user ();
61
  s->number = syscall_number;
62
  s->name = NULL;
63
}
64
 
65
void
66
get_syscall_by_name (const char *syscall_name,
67
                     struct syscall *s)
68
{
69
  syscall_warn_user ();
70
  s->number = UNKNOWN_SYSCALL;
71
  s->name = syscall_name;
72
}
73
 
74
const char **
75
get_syscall_names (void)
76
{
77
  syscall_warn_user ();
78
  return NULL;
79
}
80
 
81
#else /* ! HAVE_LIBEXPAT */
82
 
83
/* Structure which describes a syscall.  */
84
typedef struct syscall_desc
85
{
86
  /* The syscall number.  */
87
 
88
  int number;
89
 
90
  /* The syscall name.  */
91
 
92
  char *name;
93
} *syscall_desc_p;
94
DEF_VEC_P(syscall_desc_p);
95
 
96
/* Structure that represents syscalls information.  */
97
struct syscalls_info
98
{
99
  /* The syscalls.  */
100
 
101
  VEC(syscall_desc_p) *syscalls;
102
};
103
 
104
/* Callback data for syscall information parsing.  */
105
struct syscall_parsing_data
106
{
107
  /* The syscalls_info we are building.  */
108
 
109
  struct syscalls_info *sysinfo;
110
};
111
 
112
/* Structure used to store information about the available syscalls in
113
   the system.  */
114
static const struct syscalls_info *sysinfo = NULL;
115
 
116
/* A flag to tell if we already initialized the structure above.  */
117
static int have_initialized_sysinfo = 0;
118
 
119
/* The filename of the syscall's XML.  */
120
static const char *xml_syscall_file = NULL;
121
 
122
static struct syscalls_info *
123
allocate_syscalls_info (void)
124
{
125
  return XZALLOC (struct syscalls_info);
126
}
127
 
128
static void
129
sysinfo_free_syscalls_desc (struct syscall_desc *sd)
130
{
131
  xfree (sd->name);
132
}
133
 
134
static void
135
free_syscalls_info (void *arg)
136
{
137
  struct syscalls_info *sysinfo = arg;
138
  struct syscall_desc *sysdesc;
139
  int i;
140
 
141
  for (i = 0;
142
       VEC_iterate (syscall_desc_p, sysinfo->syscalls, i, sysdesc);
143
       i++)
144
    sysinfo_free_syscalls_desc (sysdesc);
145
  VEC_free (syscall_desc_p, sysinfo->syscalls);
146
 
147
  xfree (sysinfo);
148
}
149
 
150
struct cleanup *
151
make_cleanup_free_syscalls_info (struct syscalls_info *sysinfo)
152
{
153
  return make_cleanup (free_syscalls_info, sysinfo);
154
}
155
 
156
static void
157
syscall_create_syscall_desc (struct syscalls_info *sysinfo,
158
                             const char *name, int number)
159
{
160
  struct syscall_desc *sysdesc = XZALLOC (struct syscall_desc);
161
 
162
  sysdesc->name = xstrdup (name);
163
  sysdesc->number = number;
164
 
165
  VEC_safe_push (syscall_desc_p, sysinfo->syscalls, sysdesc);
166
}
167
 
168
/* Handle the start of a <syscalls_info> element.  */
169
static void
170
syscall_start_syscalls_info (struct gdb_xml_parser *parser,
171
                             const struct gdb_xml_element *element,
172
                             void *user_data,
173
                             VEC(gdb_xml_value_s) *attributes)
174
{
175
  struct syscall_parsing_data *data = user_data;
176
  struct syscalls_info *sysinfo = data->sysinfo;
177
}
178
 
179
/* Handle the start of a <syscall> element.  */
180
static void
181
syscall_start_syscall (struct gdb_xml_parser *parser,
182
                       const struct gdb_xml_element *element,
183
                       void *user_data, VEC(gdb_xml_value_s) *attributes)
184
{
185
  struct syscall_parsing_data *data = user_data;
186
  struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
187
  int len, i;
188
  /* syscall info.  */
189
  char *name = NULL;
190
  int number = 0;
191
 
192
  len = VEC_length (gdb_xml_value_s, attributes);
193
 
194
  for (i = 0; i < len; i++)
195
    {
196
      if (strcmp (attrs[i].name, "name") == 0)
197
        name = attrs[i].value;
198
      else if (strcmp (attrs[i].name, "number") == 0)
199
        number = * (ULONGEST *) attrs[i].value;
200
      else
201
        internal_error (__FILE__, __LINE__,
202
                        _("Unknown attribute name '%s'."), attrs[i].name);
203
    }
204
 
205
  syscall_create_syscall_desc (data->sysinfo, name, number);
206
}
207
 
208
 
209
/* The elements and attributes of an XML syscall document.  */
210
static const struct gdb_xml_attribute syscall_attr[] = {
211
  { "number", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
212
  { "name", GDB_XML_AF_NONE, NULL, NULL },
213
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
214
};
215
 
216
static const struct gdb_xml_element syscalls_info_children[] = {
217
  { "syscall", syscall_attr, NULL,
218
    GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
219
    syscall_start_syscall, NULL },
220
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
221
};
222
 
223
static const struct gdb_xml_element syselements[] = {
224
  { "syscalls_info", NULL, syscalls_info_children,
225
    GDB_XML_EF_NONE, syscall_start_syscalls_info, NULL },
226
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
227
};
228
 
229
static struct syscalls_info *
230
syscall_parse_xml (const char *document, xml_fetch_another fetcher,
231
                   void *fetcher_baton)
232
{
233
  struct cleanup *result_cleanup;
234
  struct gdb_xml_parser *parser;
235
  struct syscall_parsing_data data;
236
  char *expanded_text;
237
  int i;
238
 
239
  parser = gdb_xml_create_parser_and_cleanup (_("syscalls info"),
240
                                              syselements, &data);
241
 
242
  memset (&data, 0, sizeof (struct syscall_parsing_data));
243
  data.sysinfo = allocate_syscalls_info ();
244
  result_cleanup = make_cleanup_free_syscalls_info (data.sysinfo);
245
 
246
  if (gdb_xml_parse (parser, document) == 0)
247
    {
248
      /* Parsed successfully.  */
249
      discard_cleanups (result_cleanup);
250
      return data.sysinfo;
251
    }
252
  else
253
    {
254
      warning (_("Could not load XML syscalls info; ignoring"));
255
      do_cleanups (result_cleanup);
256
      return NULL;
257
    }
258
}
259
 
260
/* Function responsible for initializing the information
261
   about the syscalls.  It reads the XML file and fills the
262
   struct syscalls_info with the values.
263
 
264
   Returns the struct syscalls_info if the file is valid, NULL otherwise.  */
265
static const struct syscalls_info *
266
xml_init_syscalls_info (const char *filename)
267
{
268
  char *full_file;
269
  char *dirname;
270
  struct syscalls_info *sysinfo;
271
  struct cleanup *back_to;
272
 
273
  full_file = xml_fetch_content_from_file (filename, gdb_datadir);
274
  if (full_file == NULL)
275
    return NULL;
276
 
277
  back_to = make_cleanup (xfree, full_file);
278
 
279
  dirname = ldirname (filename);
280
  if (dirname != NULL)
281
    make_cleanup (xfree, dirname);
282
 
283
  sysinfo = syscall_parse_xml (full_file, xml_fetch_content_from_file, dirname);
284
  do_cleanups (back_to);
285
 
286
  return sysinfo;
287
}
288
 
289
/* Initializes the syscalls_info structure according to the
290
   architecture.  */
291
static void
292
init_sysinfo (void)
293
{
294
  /* Did we already try to initialize the structure?  */
295
  if (have_initialized_sysinfo)
296
    return;
297
 
298
  sysinfo = xml_init_syscalls_info (xml_syscall_file);
299
 
300
  have_initialized_sysinfo = 1;
301
 
302
  if (sysinfo == NULL)
303
    {
304
      if (xml_syscall_file)
305
        warning (_("\
306
Could not load the syscall XML file `%s'."), xml_syscall_file);
307
      else
308
        warning (_("\
309
There is no XML file to open."));
310
 
311
      warning (_("\
312
GDB will not be able to display syscall names nor to verify if\n\
313
any provided syscall numbers are valid."));
314
    }
315
}
316
 
317
static int
318
xml_get_syscall_number (const struct syscalls_info *sysinfo,
319
                        const char *syscall_name)
320
{
321
  struct syscall_desc *sysdesc;
322
  int i;
323
 
324
  if (sysinfo == NULL
325
      || syscall_name == NULL)
326
    return UNKNOWN_SYSCALL;
327
 
328
  for (i = 0;
329
       VEC_iterate(syscall_desc_p, sysinfo->syscalls, i, sysdesc);
330
       i++)
331
    if (strcmp (sysdesc->name, syscall_name) == 0)
332
      return sysdesc->number;
333
 
334
  return UNKNOWN_SYSCALL;
335
}
336
 
337
static const char *
338
xml_get_syscall_name (const struct syscalls_info *sysinfo,
339
                      int syscall_number)
340
{
341
  struct syscall_desc *sysdesc;
342
  int i;
343
 
344
  if (sysinfo == NULL
345
      || syscall_number < 0)
346
    return NULL;
347
 
348
  for (i = 0;
349
       VEC_iterate(syscall_desc_p, sysinfo->syscalls, i, sysdesc);
350
       i++)
351
    if (sysdesc->number == syscall_number)
352
      return sysdesc->name;
353
 
354
  return NULL;
355
}
356
 
357
static const char **
358
xml_list_of_syscalls (const struct syscalls_info *sysinfo)
359
{
360
  struct syscall_desc *sysdesc;
361
  const char **names = NULL;
362
  int nsyscalls;
363
  int i;
364
 
365
  if (sysinfo == NULL)
366
    return NULL;
367
 
368
  nsyscalls = VEC_length (syscall_desc_p, sysinfo->syscalls);
369
  names = xmalloc ((nsyscalls + 1) * sizeof (char *));
370
 
371
  for (i = 0;
372
       VEC_iterate (syscall_desc_p, sysinfo->syscalls, i, sysdesc);
373
       i++)
374
    names[i] = sysdesc->name;
375
 
376
  names[i] = NULL;
377
 
378
  return names;
379
}
380
 
381
void
382
set_xml_syscall_file_name (const char *name)
383
{
384
  xml_syscall_file = name;
385
}
386
 
387
void
388
get_syscall_by_number (int syscall_number,
389
                       struct syscall *s)
390
{
391
  init_sysinfo ();
392
 
393
  s->number = syscall_number;
394
  s->name = xml_get_syscall_name (sysinfo, syscall_number);
395
}
396
 
397
void
398
get_syscall_by_name (const char *syscall_name,
399
                     struct syscall *s)
400
{
401
  init_sysinfo ();
402
 
403
  s->number = xml_get_syscall_number (sysinfo, syscall_name);
404
  s->name = syscall_name;
405
}
406
 
407
const char **
408
get_syscall_names (void)
409
{
410
  init_sysinfo ();
411
 
412
  return xml_list_of_syscalls (sysinfo);
413
}
414
 
415
#endif /* ! HAVE_LIBEXPAT */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.