gdb/
[deliverable/binutils-gdb.git] / gdb / memory-map.c
CommitLineData
fd79ecee
DJ
1/* Routines for handling XML memory maps provided by target.
2
4c38e0a4 3 Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
fd79ecee
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
fd79ecee
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/>. */
fd79ecee
DJ
19
20#include "defs.h"
21#include "memory-map.h"
22#include "gdb_assert.h"
23#include "exceptions.h"
24
25#include "gdb_string.h"
26
27#if !defined(HAVE_LIBEXPAT)
28
29VEC(mem_region_s) *
30parse_memory_map (const char *memory_map)
31{
32 static int have_warned;
33
34 if (!have_warned)
35 {
36 have_warned = 1;
37 warning (_("Can not parse XML memory map; XML support was disabled "
38 "at compile time"));
39 }
40
41 return NULL;
42}
43
44#else /* HAVE_LIBEXPAT */
45
46#include "xml-support.h"
fd79ecee 47
e776119f 48/* Internal parsing data passed to all XML callbacks. */
fd79ecee
DJ
49struct memory_map_parsing_data
50 {
51 VEC(mem_region_s) **memory_map;
e776119f 52 char property_name[32];
fd79ecee
DJ
53 };
54
e776119f
DJ
55/* Handle the start of a <memory> element. */
56
fd79ecee 57static void
e776119f
DJ
58memory_map_start_memory (struct gdb_xml_parser *parser,
59 const struct gdb_xml_element *element,
60 void *user_data, VEC(gdb_xml_value_s) *attributes)
fd79ecee 61{
e776119f
DJ
62 struct memory_map_parsing_data *data = user_data;
63 struct mem_region *r = VEC_safe_push (mem_region_s, *data->memory_map, NULL);
64 ULONGEST *start_p, *length_p, *type_p;
65
66 start_p = VEC_index (gdb_xml_value_s, attributes, 0)->value;
67 length_p = VEC_index (gdb_xml_value_s, attributes, 1)->value;
68 type_p = VEC_index (gdb_xml_value_s, attributes, 2)->value;
69
70 mem_region_init (r);
71 r->lo = *start_p;
72 r->hi = r->lo + *length_p;
73 r->attrib.mode = *type_p;
74 r->attrib.blocksize = -1;
fd79ecee
DJ
75}
76
e776119f
DJ
77/* Handle the end of a <memory> element. Verify that any necessary
78 children were present. */
fd79ecee
DJ
79
80static void
e776119f
DJ
81memory_map_end_memory (struct gdb_xml_parser *parser,
82 const struct gdb_xml_element *element,
83 void *user_data, const char *body_text)
fd79ecee 84{
e776119f
DJ
85 struct memory_map_parsing_data *data = user_data;
86 struct mem_region *r = VEC_last (mem_region_s, *data->memory_map);
fd79ecee 87
e776119f
DJ
88 if (r->attrib.mode == MEM_FLASH && r->attrib.blocksize == -1)
89 gdb_xml_error (parser, _("Flash block size is not set"));
fd79ecee
DJ
90}
91
e776119f
DJ
92/* Handle the start of a <property> element by saving the name
93 attribute for later. */
fd79ecee
DJ
94
95static void
e776119f
DJ
96memory_map_start_property (struct gdb_xml_parser *parser,
97 const struct gdb_xml_element *element,
98 void *user_data, VEC(gdb_xml_value_s) *attributes)
fd79ecee 99{
e776119f
DJ
100 struct memory_map_parsing_data *data = user_data;
101 char *name;
fd79ecee 102
e776119f
DJ
103 name = VEC_index (gdb_xml_value_s, attributes, 0)->value;
104 snprintf (data->property_name, sizeof (data->property_name), "%s", name);
fd79ecee
DJ
105}
106
e776119f 107/* Handle the end of a <property> element and its value. */
fd79ecee 108
fd79ecee 109static void
e776119f
DJ
110memory_map_end_property (struct gdb_xml_parser *parser,
111 const struct gdb_xml_element *element,
112 void *user_data, const char *body_text)
fd79ecee 113{
e776119f
DJ
114 struct memory_map_parsing_data *data = user_data;
115 char *name = data->property_name;
fd79ecee 116
e776119f 117 if (strcmp (name, "blocksize") == 0)
fd79ecee 118 {
e776119f 119 struct mem_region *r = VEC_last (mem_region_s, *data->memory_map);
fd79ecee 120
e776119f
DJ
121 r->attrib.blocksize = gdb_xml_parse_ulongest (parser, body_text);
122 }
123 else
124 gdb_xml_debug (parser, _("Unknown property \"%s\""), name);
fd79ecee
DJ
125}
126
e776119f
DJ
127/* Discard the constructed memory map (if an error occurs). */
128
fd79ecee
DJ
129static void
130clear_result (void *p)
131{
132 VEC(mem_region_s) **result = p;
133 VEC_free (mem_region_s, *result);
134 *result = NULL;
135}
136
e776119f
DJ
137/* The allowed elements and attributes for an XML memory map. */
138
139const struct gdb_xml_attribute property_attributes[] = {
140 { "name", GDB_XML_AF_NONE, NULL, NULL },
141 { NULL, GDB_XML_AF_NONE, NULL, NULL }
142};
143
144const struct gdb_xml_element memory_children[] = {
145 { "property", property_attributes, NULL,
146 GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
147 memory_map_start_property, memory_map_end_property },
148 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
149};
150
151const struct gdb_xml_enum memory_type_enum[] = {
152 { "ram", MEM_RW },
153 { "rom", MEM_RO },
154 { "flash", MEM_FLASH },
155 { NULL, 0 }
156};
157
158const struct gdb_xml_attribute memory_attributes[] = {
159 { "start", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
160 { "length", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
161 { "type", GDB_XML_AF_NONE, gdb_xml_parse_attr_enum, &memory_type_enum },
162 { NULL, GDB_XML_AF_NONE, NULL, NULL }
163};
164
165const struct gdb_xml_element memory_map_children[] = {
166 { "memory", memory_attributes, memory_children, GDB_XML_EF_REPEATABLE,
167 memory_map_start_memory, memory_map_end_memory },
168 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
169};
170
171const struct gdb_xml_element memory_map_elements[] = {
172 { "memory-map", NULL, memory_map_children, GDB_XML_EF_NONE,
173 NULL, NULL },
174 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
175};
176
fd79ecee
DJ
177VEC(mem_region_s) *
178parse_memory_map (const char *memory_map)
179{
e776119f 180 struct gdb_xml_parser *parser;
fd79ecee 181 VEC(mem_region_s) *result = NULL;
e776119f 182 struct cleanup *before_deleting_result, *back_to;
f6071bfa 183 struct memory_map_parsing_data data = { NULL };
fd79ecee 184
e776119f
DJ
185 back_to = make_cleanup (null_cleanup, NULL);
186 parser = gdb_xml_create_parser_and_cleanup (_("target memory map"),
187 memory_map_elements, &data);
fd79ecee 188
fd79ecee
DJ
189 /* Note: 'clear_result' will zero 'result'. */
190 before_deleting_result = make_cleanup (clear_result, &result);
fd79ecee
DJ
191 data.memory_map = &result;
192
e776119f 193 if (gdb_xml_parse (parser, memory_map) == 0)
fd79ecee
DJ
194 /* Parsed successfully, don't need to delete the result. */
195 discard_cleanups (before_deleting_result);
196
fd79ecee
DJ
197 do_cleanups (back_to);
198 return result;
199}
200
201#endif /* HAVE_LIBEXPAT */
This page took 0.375136 seconds and 4 git commands to generate.