1 /* Routines for handling XML memory maps provided by target. 2 3 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 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 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 "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 30 VEC(mem_region_s) * 31 parse_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" 48 49 /* Internal parsing data passed to all XML callbacks. */ 50 struct memory_map_parsing_data 51 { 52 VEC(mem_region_s) **memory_map; 53 char property_name[32]; 54 }; 55 56 /* Handle the start of a <memory> element. */ 57 58 static void 59 memory_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) 62 { 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 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; 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; 76 } 77 78 /* Handle the end of a <memory> element. Verify that any necessary 79 children were present. */ 80 81 static void 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) 85 { 86 struct memory_map_parsing_data *data = user_data; 87 struct mem_region *r = VEC_last (mem_region_s, *data->memory_map); 88 89 if (r->attrib.mode == MEM_FLASH && r->attrib.blocksize == -1) 90 gdb_xml_error (parser, _("Flash block size is not set")); 91 } 92 93 /* Handle the start of a <property> element by saving the name 94 attribute for later. */ 95 96 static void 97 memory_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) 100 { 101 struct memory_map_parsing_data *data = user_data; 102 char *name; 103 104 name = xml_find_attribute (attributes, "name")->value; 105 snprintf (data->property_name, sizeof (data->property_name), "%s", name); 106 } 107 108 /* Handle the end of a <property> element and its value. */ 109 110 static void 111 memory_map_end_property (struct gdb_xml_parser *parser, 112 const struct gdb_xml_element *element, 113 void *user_data, const char *body_text) 114 { 115 struct memory_map_parsing_data *data = user_data; 116 char *name = data->property_name; 117 118 if (strcmp (name, "blocksize") == 0) 119 { 120 struct mem_region *r = VEC_last (mem_region_s, *data->memory_map); 121 122 r->attrib.blocksize = gdb_xml_parse_ulongest (parser, body_text); 123 } 124 else 125 gdb_xml_debug (parser, _("Unknown property \"%s\""), name); 126 } 127 128 /* Discard the constructed memory map (if an error occurs). */ 129 130 static void 131 clear_result (void *p) 132 { 133 VEC(mem_region_s) **result = p; 134 VEC_free (mem_region_s, *result); 135 *result = NULL; 136 } 137 138 /* The allowed elements and attributes for an XML memory map. */ 139 140 const struct gdb_xml_attribute property_attributes[] = { 141 { "name", GDB_XML_AF_NONE, NULL, NULL }, 142 { NULL, GDB_XML_AF_NONE, NULL, NULL } 143 }; 144 145 const 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 152 const struct gdb_xml_enum memory_type_enum[] = { 153 { "ram", MEM_RW }, 154 { "rom", MEM_RO }, 155 { "flash", MEM_FLASH }, 156 { NULL, 0 } 157 }; 158 159 const 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 166 const 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 172 const 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 178 VEC(mem_region_s) * 179 parse_memory_map (const char *memory_map) 180 { 181 VEC(mem_region_s) *result = NULL; 182 struct cleanup *back_to; 183 struct memory_map_parsing_data data = { NULL }; 184 185 data.memory_map = &result; 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 } 194 195 do_cleanups (back_to); 196 return NULL; 197 } 198 199 #endif /* HAVE_LIBEXPAT */ 200