GDB (API)
|
00001 /* Routines for handling XML memory maps provided by target. 00002 00003 Copyright (C) 2006-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "defs.h" 00021 #include "memory-map.h" 00022 #include "gdb_assert.h" 00023 #include "exceptions.h" 00024 00025 #include "gdb_string.h" 00026 00027 #if !defined(HAVE_LIBEXPAT) 00028 00029 VEC(mem_region_s) * 00030 parse_memory_map (const char *memory_map) 00031 { 00032 static int have_warned; 00033 00034 if (!have_warned) 00035 { 00036 have_warned = 1; 00037 warning (_("Can not parse XML memory map; XML support was disabled " 00038 "at compile time")); 00039 } 00040 00041 return NULL; 00042 } 00043 00044 #else /* HAVE_LIBEXPAT */ 00045 00046 #include "xml-support.h" 00047 00048 /* Internal parsing data passed to all XML callbacks. */ 00049 struct memory_map_parsing_data 00050 { 00051 VEC(mem_region_s) **memory_map; 00052 char property_name[32]; 00053 }; 00054 00055 /* Handle the start of a <memory> element. */ 00056 00057 static void 00058 memory_map_start_memory (struct gdb_xml_parser *parser, 00059 const struct gdb_xml_element *element, 00060 void *user_data, VEC(gdb_xml_value_s) *attributes) 00061 { 00062 struct memory_map_parsing_data *data = user_data; 00063 struct mem_region *r = VEC_safe_push (mem_region_s, *data->memory_map, NULL); 00064 ULONGEST *start_p, *length_p, *type_p; 00065 00066 start_p = xml_find_attribute (attributes, "start")->value; 00067 length_p = xml_find_attribute (attributes, "length")->value; 00068 type_p = xml_find_attribute (attributes, "type")->value; 00069 00070 mem_region_init (r); 00071 r->lo = *start_p; 00072 r->hi = r->lo + *length_p; 00073 r->attrib.mode = *type_p; 00074 r->attrib.blocksize = -1; 00075 } 00076 00077 /* Handle the end of a <memory> element. Verify that any necessary 00078 children were present. */ 00079 00080 static void 00081 memory_map_end_memory (struct gdb_xml_parser *parser, 00082 const struct gdb_xml_element *element, 00083 void *user_data, const char *body_text) 00084 { 00085 struct memory_map_parsing_data *data = user_data; 00086 struct mem_region *r = VEC_last (mem_region_s, *data->memory_map); 00087 00088 if (r->attrib.mode == MEM_FLASH && r->attrib.blocksize == -1) 00089 gdb_xml_error (parser, _("Flash block size is not set")); 00090 } 00091 00092 /* Handle the start of a <property> element by saving the name 00093 attribute for later. */ 00094 00095 static void 00096 memory_map_start_property (struct gdb_xml_parser *parser, 00097 const struct gdb_xml_element *element, 00098 void *user_data, VEC(gdb_xml_value_s) *attributes) 00099 { 00100 struct memory_map_parsing_data *data = user_data; 00101 char *name; 00102 00103 name = xml_find_attribute (attributes, "name")->value; 00104 snprintf (data->property_name, sizeof (data->property_name), "%s", name); 00105 } 00106 00107 /* Handle the end of a <property> element and its value. */ 00108 00109 static void 00110 memory_map_end_property (struct gdb_xml_parser *parser, 00111 const struct gdb_xml_element *element, 00112 void *user_data, const char *body_text) 00113 { 00114 struct memory_map_parsing_data *data = user_data; 00115 char *name = data->property_name; 00116 00117 if (strcmp (name, "blocksize") == 0) 00118 { 00119 struct mem_region *r = VEC_last (mem_region_s, *data->memory_map); 00120 00121 r->attrib.blocksize = gdb_xml_parse_ulongest (parser, body_text); 00122 } 00123 else 00124 gdb_xml_debug (parser, _("Unknown property \"%s\""), name); 00125 } 00126 00127 /* Discard the constructed memory map (if an error occurs). */ 00128 00129 static void 00130 clear_result (void *p) 00131 { 00132 VEC(mem_region_s) **result = p; 00133 VEC_free (mem_region_s, *result); 00134 *result = NULL; 00135 } 00136 00137 /* The allowed elements and attributes for an XML memory map. */ 00138 00139 const struct gdb_xml_attribute property_attributes[] = { 00140 { "name", GDB_XML_AF_NONE, NULL, NULL }, 00141 { NULL, GDB_XML_AF_NONE, NULL, NULL } 00142 }; 00143 00144 const struct gdb_xml_element memory_children[] = { 00145 { "property", property_attributes, NULL, 00146 GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL, 00147 memory_map_start_property, memory_map_end_property }, 00148 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 00149 }; 00150 00151 const struct gdb_xml_enum memory_type_enum[] = { 00152 { "ram", MEM_RW }, 00153 { "rom", MEM_RO }, 00154 { "flash", MEM_FLASH }, 00155 { NULL, 0 } 00156 }; 00157 00158 const struct gdb_xml_attribute memory_attributes[] = { 00159 { "start", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 00160 { "length", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 00161 { "type", GDB_XML_AF_NONE, gdb_xml_parse_attr_enum, &memory_type_enum }, 00162 { NULL, GDB_XML_AF_NONE, NULL, NULL } 00163 }; 00164 00165 const struct gdb_xml_element memory_map_children[] = { 00166 { "memory", memory_attributes, memory_children, GDB_XML_EF_REPEATABLE, 00167 memory_map_start_memory, memory_map_end_memory }, 00168 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 00169 }; 00170 00171 const struct gdb_xml_element memory_map_elements[] = { 00172 { "memory-map", NULL, memory_map_children, GDB_XML_EF_NONE, 00173 NULL, NULL }, 00174 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 00175 }; 00176 00177 VEC(mem_region_s) * 00178 parse_memory_map (const char *memory_map) 00179 { 00180 VEC(mem_region_s) *result = NULL; 00181 struct cleanup *back_to; 00182 struct memory_map_parsing_data data = { NULL }; 00183 00184 data.memory_map = &result; 00185 back_to = make_cleanup (clear_result, &result); 00186 if (gdb_xml_parse_quick (_("target memory map"), NULL, memory_map_elements, 00187 memory_map, &data) == 0) 00188 { 00189 /* Parsed successfully, keep the result. */ 00190 discard_cleanups (back_to); 00191 return result; 00192 } 00193 00194 do_cleanups (back_to); 00195 return NULL; 00196 } 00197 00198 #endif /* HAVE_LIBEXPAT */