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