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