1*5796c8dcSSimon Schubert /* Routines for handling XML memory maps provided by target. 2*5796c8dcSSimon Schubert 3*5796c8dcSSimon Schubert Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc. 4*5796c8dcSSimon Schubert 5*5796c8dcSSimon Schubert This file is part of GDB. 6*5796c8dcSSimon Schubert 7*5796c8dcSSimon Schubert This program is free software; you can redistribute it and/or modify 8*5796c8dcSSimon Schubert it under the terms of the GNU General Public License as published by 9*5796c8dcSSimon Schubert the Free Software Foundation; either version 3 of the License, or 10*5796c8dcSSimon Schubert (at your option) any later version. 11*5796c8dcSSimon Schubert 12*5796c8dcSSimon Schubert This program is distributed in the hope that it will be useful, 13*5796c8dcSSimon Schubert but WITHOUT ANY WARRANTY; without even the implied warranty of 14*5796c8dcSSimon Schubert MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*5796c8dcSSimon Schubert GNU General Public License for more details. 16*5796c8dcSSimon Schubert 17*5796c8dcSSimon Schubert You should have received a copy of the GNU General Public License 18*5796c8dcSSimon Schubert along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19*5796c8dcSSimon Schubert 20*5796c8dcSSimon Schubert #include "defs.h" 21*5796c8dcSSimon Schubert #include "memory-map.h" 22*5796c8dcSSimon Schubert #include "gdb_assert.h" 23*5796c8dcSSimon Schubert #include "exceptions.h" 24*5796c8dcSSimon Schubert 25*5796c8dcSSimon Schubert #include "gdb_string.h" 26*5796c8dcSSimon Schubert 27*5796c8dcSSimon Schubert #if !defined(HAVE_LIBEXPAT) 28*5796c8dcSSimon Schubert 29*5796c8dcSSimon Schubert VEC(mem_region_s) * 30*5796c8dcSSimon Schubert parse_memory_map (const char *memory_map) 31*5796c8dcSSimon Schubert { 32*5796c8dcSSimon Schubert static int have_warned; 33*5796c8dcSSimon Schubert 34*5796c8dcSSimon Schubert if (!have_warned) 35*5796c8dcSSimon Schubert { 36*5796c8dcSSimon Schubert have_warned = 1; 37*5796c8dcSSimon Schubert warning (_("Can not parse XML memory map; XML support was disabled " 38*5796c8dcSSimon Schubert "at compile time")); 39*5796c8dcSSimon Schubert } 40*5796c8dcSSimon Schubert 41*5796c8dcSSimon Schubert return NULL; 42*5796c8dcSSimon Schubert } 43*5796c8dcSSimon Schubert 44*5796c8dcSSimon Schubert #else /* HAVE_LIBEXPAT */ 45*5796c8dcSSimon Schubert 46*5796c8dcSSimon Schubert #include "xml-support.h" 47*5796c8dcSSimon Schubert 48*5796c8dcSSimon Schubert /* Internal parsing data passed to all XML callbacks. */ 49*5796c8dcSSimon Schubert struct memory_map_parsing_data 50*5796c8dcSSimon Schubert { 51*5796c8dcSSimon Schubert VEC(mem_region_s) **memory_map; 52*5796c8dcSSimon Schubert char property_name[32]; 53*5796c8dcSSimon Schubert }; 54*5796c8dcSSimon Schubert 55*5796c8dcSSimon Schubert /* Handle the start of a <memory> element. */ 56*5796c8dcSSimon Schubert 57*5796c8dcSSimon Schubert static void 58*5796c8dcSSimon Schubert memory_map_start_memory (struct gdb_xml_parser *parser, 59*5796c8dcSSimon Schubert const struct gdb_xml_element *element, 60*5796c8dcSSimon Schubert void *user_data, VEC(gdb_xml_value_s) *attributes) 61*5796c8dcSSimon Schubert { 62*5796c8dcSSimon Schubert struct memory_map_parsing_data *data = user_data; 63*5796c8dcSSimon Schubert struct mem_region *r = VEC_safe_push (mem_region_s, *data->memory_map, NULL); 64*5796c8dcSSimon Schubert ULONGEST *start_p, *length_p, *type_p; 65*5796c8dcSSimon Schubert 66*5796c8dcSSimon Schubert start_p = VEC_index (gdb_xml_value_s, attributes, 0)->value; 67*5796c8dcSSimon Schubert length_p = VEC_index (gdb_xml_value_s, attributes, 1)->value; 68*5796c8dcSSimon Schubert type_p = VEC_index (gdb_xml_value_s, attributes, 2)->value; 69*5796c8dcSSimon Schubert 70*5796c8dcSSimon Schubert mem_region_init (r); 71*5796c8dcSSimon Schubert r->lo = *start_p; 72*5796c8dcSSimon Schubert r->hi = r->lo + *length_p; 73*5796c8dcSSimon Schubert r->attrib.mode = *type_p; 74*5796c8dcSSimon Schubert r->attrib.blocksize = -1; 75*5796c8dcSSimon Schubert } 76*5796c8dcSSimon Schubert 77*5796c8dcSSimon Schubert /* Handle the end of a <memory> element. Verify that any necessary 78*5796c8dcSSimon Schubert children were present. */ 79*5796c8dcSSimon Schubert 80*5796c8dcSSimon Schubert static void 81*5796c8dcSSimon Schubert memory_map_end_memory (struct gdb_xml_parser *parser, 82*5796c8dcSSimon Schubert const struct gdb_xml_element *element, 83*5796c8dcSSimon Schubert void *user_data, const char *body_text) 84*5796c8dcSSimon Schubert { 85*5796c8dcSSimon Schubert struct memory_map_parsing_data *data = user_data; 86*5796c8dcSSimon Schubert struct mem_region *r = VEC_last (mem_region_s, *data->memory_map); 87*5796c8dcSSimon Schubert 88*5796c8dcSSimon Schubert if (r->attrib.mode == MEM_FLASH && r->attrib.blocksize == -1) 89*5796c8dcSSimon Schubert gdb_xml_error (parser, _("Flash block size is not set")); 90*5796c8dcSSimon Schubert } 91*5796c8dcSSimon Schubert 92*5796c8dcSSimon Schubert /* Handle the start of a <property> element by saving the name 93*5796c8dcSSimon Schubert attribute for later. */ 94*5796c8dcSSimon Schubert 95*5796c8dcSSimon Schubert static void 96*5796c8dcSSimon Schubert memory_map_start_property (struct gdb_xml_parser *parser, 97*5796c8dcSSimon Schubert const struct gdb_xml_element *element, 98*5796c8dcSSimon Schubert void *user_data, VEC(gdb_xml_value_s) *attributes) 99*5796c8dcSSimon Schubert { 100*5796c8dcSSimon Schubert struct memory_map_parsing_data *data = user_data; 101*5796c8dcSSimon Schubert char *name; 102*5796c8dcSSimon Schubert 103*5796c8dcSSimon Schubert name = VEC_index (gdb_xml_value_s, attributes, 0)->value; 104*5796c8dcSSimon Schubert snprintf (data->property_name, sizeof (data->property_name), "%s", name); 105*5796c8dcSSimon Schubert } 106*5796c8dcSSimon Schubert 107*5796c8dcSSimon Schubert /* Handle the end of a <property> element and its value. */ 108*5796c8dcSSimon Schubert 109*5796c8dcSSimon Schubert static void 110*5796c8dcSSimon Schubert memory_map_end_property (struct gdb_xml_parser *parser, 111*5796c8dcSSimon Schubert const struct gdb_xml_element *element, 112*5796c8dcSSimon Schubert void *user_data, const char *body_text) 113*5796c8dcSSimon Schubert { 114*5796c8dcSSimon Schubert struct memory_map_parsing_data *data = user_data; 115*5796c8dcSSimon Schubert char *name = data->property_name; 116*5796c8dcSSimon Schubert 117*5796c8dcSSimon Schubert if (strcmp (name, "blocksize") == 0) 118*5796c8dcSSimon Schubert { 119*5796c8dcSSimon Schubert struct mem_region *r = VEC_last (mem_region_s, *data->memory_map); 120*5796c8dcSSimon Schubert 121*5796c8dcSSimon Schubert r->attrib.blocksize = gdb_xml_parse_ulongest (parser, body_text); 122*5796c8dcSSimon Schubert } 123*5796c8dcSSimon Schubert else 124*5796c8dcSSimon Schubert gdb_xml_debug (parser, _("Unknown property \"%s\""), name); 125*5796c8dcSSimon Schubert } 126*5796c8dcSSimon Schubert 127*5796c8dcSSimon Schubert /* Discard the constructed memory map (if an error occurs). */ 128*5796c8dcSSimon Schubert 129*5796c8dcSSimon Schubert static void 130*5796c8dcSSimon Schubert clear_result (void *p) 131*5796c8dcSSimon Schubert { 132*5796c8dcSSimon Schubert VEC(mem_region_s) **result = p; 133*5796c8dcSSimon Schubert VEC_free (mem_region_s, *result); 134*5796c8dcSSimon Schubert *result = NULL; 135*5796c8dcSSimon Schubert } 136*5796c8dcSSimon Schubert 137*5796c8dcSSimon Schubert /* The allowed elements and attributes for an XML memory map. */ 138*5796c8dcSSimon Schubert 139*5796c8dcSSimon Schubert const struct gdb_xml_attribute property_attributes[] = { 140*5796c8dcSSimon Schubert { "name", GDB_XML_AF_NONE, NULL, NULL }, 141*5796c8dcSSimon Schubert { NULL, GDB_XML_AF_NONE, NULL, NULL } 142*5796c8dcSSimon Schubert }; 143*5796c8dcSSimon Schubert 144*5796c8dcSSimon Schubert const struct gdb_xml_element memory_children[] = { 145*5796c8dcSSimon Schubert { "property", property_attributes, NULL, 146*5796c8dcSSimon Schubert GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL, 147*5796c8dcSSimon Schubert memory_map_start_property, memory_map_end_property }, 148*5796c8dcSSimon Schubert { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 149*5796c8dcSSimon Schubert }; 150*5796c8dcSSimon Schubert 151*5796c8dcSSimon Schubert const struct gdb_xml_enum memory_type_enum[] = { 152*5796c8dcSSimon Schubert { "ram", MEM_RW }, 153*5796c8dcSSimon Schubert { "rom", MEM_RO }, 154*5796c8dcSSimon Schubert { "flash", MEM_FLASH }, 155*5796c8dcSSimon Schubert { NULL, 0 } 156*5796c8dcSSimon Schubert }; 157*5796c8dcSSimon Schubert 158*5796c8dcSSimon Schubert const struct gdb_xml_attribute memory_attributes[] = { 159*5796c8dcSSimon Schubert { "start", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 160*5796c8dcSSimon Schubert { "length", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL }, 161*5796c8dcSSimon Schubert { "type", GDB_XML_AF_NONE, gdb_xml_parse_attr_enum, &memory_type_enum }, 162*5796c8dcSSimon Schubert { NULL, GDB_XML_AF_NONE, NULL, NULL } 163*5796c8dcSSimon Schubert }; 164*5796c8dcSSimon Schubert 165*5796c8dcSSimon Schubert const struct gdb_xml_element memory_map_children[] = { 166*5796c8dcSSimon Schubert { "memory", memory_attributes, memory_children, GDB_XML_EF_REPEATABLE, 167*5796c8dcSSimon Schubert memory_map_start_memory, memory_map_end_memory }, 168*5796c8dcSSimon Schubert { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 169*5796c8dcSSimon Schubert }; 170*5796c8dcSSimon Schubert 171*5796c8dcSSimon Schubert const struct gdb_xml_element memory_map_elements[] = { 172*5796c8dcSSimon Schubert { "memory-map", NULL, memory_map_children, GDB_XML_EF_NONE, 173*5796c8dcSSimon Schubert NULL, NULL }, 174*5796c8dcSSimon Schubert { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } 175*5796c8dcSSimon Schubert }; 176*5796c8dcSSimon Schubert 177*5796c8dcSSimon Schubert VEC(mem_region_s) * 178*5796c8dcSSimon Schubert parse_memory_map (const char *memory_map) 179*5796c8dcSSimon Schubert { 180*5796c8dcSSimon Schubert struct gdb_xml_parser *parser; 181*5796c8dcSSimon Schubert VEC(mem_region_s) *result = NULL; 182*5796c8dcSSimon Schubert struct cleanup *before_deleting_result, *back_to; 183*5796c8dcSSimon Schubert struct memory_map_parsing_data data = { NULL }; 184*5796c8dcSSimon Schubert 185*5796c8dcSSimon Schubert back_to = make_cleanup (null_cleanup, NULL); 186*5796c8dcSSimon Schubert parser = gdb_xml_create_parser_and_cleanup (_("target memory map"), 187*5796c8dcSSimon Schubert memory_map_elements, &data); 188*5796c8dcSSimon Schubert 189*5796c8dcSSimon Schubert /* Note: 'clear_result' will zero 'result'. */ 190*5796c8dcSSimon Schubert before_deleting_result = make_cleanup (clear_result, &result); 191*5796c8dcSSimon Schubert data.memory_map = &result; 192*5796c8dcSSimon Schubert 193*5796c8dcSSimon Schubert if (gdb_xml_parse (parser, memory_map) == 0) 194*5796c8dcSSimon Schubert /* Parsed successfully, don't need to delete the result. */ 195*5796c8dcSSimon Schubert discard_cleanups (before_deleting_result); 196*5796c8dcSSimon Schubert 197*5796c8dcSSimon Schubert do_cleanups (back_to); 198*5796c8dcSSimon Schubert return result; 199*5796c8dcSSimon Schubert } 200*5796c8dcSSimon Schubert 201*5796c8dcSSimon Schubert #endif /* HAVE_LIBEXPAT */ 202