GDB (API)
/home/stan/gdb/src/gdb/memory-map.c
Go to the documentation of this file.
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 */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines