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