1 /* Routines for handling XML memory maps provided by target. 2 3 Copyright (C) 2006-2020 Free Software Foundation, Inc. 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 9 the Free Software Foundation; either version 3 of the License, or 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 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #include "defs.h" 21 #include "memory-map.h" 22 23 #if !defined(HAVE_LIBEXPAT) 24 25 std::vector<mem_region> 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 std::vector<mem_region> (); 38 } 39 40 #else /* HAVE_LIBEXPAT */ 41 42 #include "xml-support.h" 43 44 /* Internal parsing data passed to all XML callbacks. */ 45 struct memory_map_parsing_data 46 { 47 memory_map_parsing_data (std::vector<mem_region> *memory_map_) 48 : memory_map (memory_map_) 49 {} 50 51 std::vector<mem_region> *memory_map; 52 53 std::string property_name; 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, 62 std::vector<gdb_xml_value> &attributes) 63 { 64 struct memory_map_parsing_data *data 65 = (struct memory_map_parsing_data *) user_data; 66 ULONGEST *start_p, *length_p, *type_p; 67 68 start_p 69 = (ULONGEST *) xml_find_attribute (attributes, "start")->value.get (); 70 length_p 71 = (ULONGEST *) xml_find_attribute (attributes, "length")->value.get (); 72 type_p 73 = (ULONGEST *) xml_find_attribute (attributes, "type")->value.get (); 74 75 data->memory_map->emplace_back (*start_p, *start_p + *length_p, 76 (enum mem_access_mode) *type_p); 77 } 78 79 /* Handle the end of a <memory> element. Verify that any necessary 80 children were present. */ 81 82 static void 83 memory_map_end_memory (struct gdb_xml_parser *parser, 84 const struct gdb_xml_element *element, 85 void *user_data, const char *body_text) 86 { 87 struct memory_map_parsing_data *data 88 = (struct memory_map_parsing_data *) user_data; 89 const mem_region &r = data->memory_map->back (); 90 91 if (r.attrib.mode == MEM_FLASH && r.attrib.blocksize == -1) 92 gdb_xml_error (parser, _("Flash block size is not set")); 93 } 94 95 /* Handle the start of a <property> element by saving the name 96 attribute for later. */ 97 98 static void 99 memory_map_start_property (struct gdb_xml_parser *parser, 100 const struct gdb_xml_element *element, 101 void *user_data, 102 std::vector<gdb_xml_value> &attributes) 103 { 104 struct memory_map_parsing_data *data 105 = (struct memory_map_parsing_data *) user_data; 106 char *name; 107 108 name = (char *) xml_find_attribute (attributes, "name")->value.get (); 109 data->property_name.assign (name); 110 } 111 112 /* Handle the end of a <property> element and its value. */ 113 114 static void 115 memory_map_end_property (struct gdb_xml_parser *parser, 116 const struct gdb_xml_element *element, 117 void *user_data, const char *body_text) 118 { 119 struct memory_map_parsing_data *data 120 = (struct memory_map_parsing_data *) user_data; 121 122 if (data->property_name == "blocksize") 123 { 124 mem_region &r = data->memory_map->back (); 125 126 r.attrib.blocksize = gdb_xml_parse_ulongest (parser, body_text); 127 } 128 else 129 gdb_xml_debug (parser, _("Unknown property \"%s\""), 130 data->property_name.c_str ()); 131 } 132 133 /* The allowed elements and attributes for an XML memory map. */ 134 135 const struct gdb_xml_attribute property_attributes[] = { 136 { "name", GDB_XML_AF_NONE, NULL, NULL }, 137 { NULL, GDB_XML_AF_NONE, NULL, NULL } 138 }; 139 140 const struct gdb_xml_element memory_children[] = { 141 { "property", property_attributes, NULL, 142 GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL, 143 memory_map_start_property, memory_map_end_property }, 144 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 145 }; 146 147 const struct gdb_xml_enum memory_type_enum[] = { 148 { "ram", MEM_RW }, 149 { "rom", MEM_RO }, 150 { "flash", MEM_FLASH }, 151 { NULL, 0 } 152 }; 153 154 const struct gdb_xml_attribute memory_attributes[] = { 155 { "start", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 156 { "length", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 157 { "type", GDB_XML_AF_NONE, gdb_xml_parse_attr_enum, &memory_type_enum }, 158 { NULL, GDB_XML_AF_NONE, NULL, NULL } 159 }; 160 161 const struct gdb_xml_element memory_map_children[] = { 162 { "memory", memory_attributes, memory_children, GDB_XML_EF_REPEATABLE, 163 memory_map_start_memory, memory_map_end_memory }, 164 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 165 }; 166 167 const struct gdb_xml_element memory_map_elements[] = { 168 { "memory-map", NULL, memory_map_children, GDB_XML_EF_NONE, 169 NULL, NULL }, 170 { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 171 }; 172 173 std::vector<mem_region> 174 parse_memory_map (const char *memory_map) 175 { 176 std::vector<mem_region> ret; 177 memory_map_parsing_data data (&ret); 178 179 if (gdb_xml_parse_quick (_("target memory map"), NULL, memory_map_elements, 180 memory_map, &data) == 0) 181 { 182 /* Parsed successfully, keep the result. */ 183 return ret; 184 } 185 186 return std::vector<mem_region> (); 187 } 188 189 #endif /* HAVE_LIBEXPAT */ 190