gdb/sim: add support for exporting memory map
authorMike Frysinger <vapier@gentoo.org>
Wed, 30 Dec 2015 04:52:57 +0000 (23:52 -0500)
committerMike Frysinger <vapier@gentoo.org>
Thu, 7 Jan 2021 17:18:59 +0000 (12:18 -0500)
This allows gdb to quickly dump & process the memory map that the sim
knows about.  This isn't fully accurate, but is largely limited by the
gdb memory map format.  While the sim supports RWX bits, gdb can only
handle RW or RO regions.

gdb/ChangeLog
gdb/remote-sim.c
include/gdb/ChangeLog
include/gdb/remote-sim.h
sim/common/ChangeLog
sim/common/sim-core.c

index f3357d5e659a3674ebafb691fb0bd6da76c7e402..02c561de07e9404b52a30b5ffb7819d66e922c8a 100644 (file)
@@ -1,3 +1,9 @@
+2021-01-07  Mike Frysinger  <vapier@gentoo.org>
+
+       * remote-sim.c: Include memory-map.h.
+       (gdbsim_target): Define memory_map override.
+       (gdbsim_target::memory_map): Define.
+
 2021-01-07  Tom Tromey  <tromey@adacore.com>
 
        * ada-lang.c (do_full_match): Conditionally skip "_ada_" prefix.
index c4f3913edbad31b0532d0aedea2918eccf6621c0..b21a4e80ee6a4f6cd5cf731bf709d090b1392d7e 100644 (file)
@@ -42,6 +42,7 @@
 #include "readline/readline.h"
 #include "gdbthread.h"
 #include "gdbsupport/byte-vector.h"
+#include "memory-map.h"
 
 /* Prototypes */
 
@@ -164,6 +165,7 @@ struct gdbsim_target final
 
   bool has_all_memory ()  override;
   bool has_memory ()  override;
+  std::vector<mem_region> memory_map () override;
 
 private:
   sim_inferior_data *get_inferior_data_by_ptid (ptid_t ptid,
@@ -1270,6 +1272,22 @@ gdbsim_target::has_memory ()
   return true;
 }
 
+/* Get memory map from the simulator.  */
+
+std::vector<mem_region>
+gdbsim_target::memory_map ()
+{
+  struct sim_inferior_data *sim_data
+    = get_sim_inferior_data (current_inferior (), SIM_INSTANCE_NEEDED);
+  std::vector<mem_region> result;
+  gdb::unique_xmalloc_ptr<char> text (sim_memory_map (sim_data->gdbsim_desc));
+
+  if (text != nullptr)
+    result = parse_memory_map (text.get ());
+
+  return result;
+}
+
 void _initialize_remote_sim ();
 void
 _initialize_remote_sim ()
index 0ae9e0b18a7c56dcd66e355ca963dfb67932fe9b..27efbaf877fec4502f25a7e79dae0edbb9e71f9d 100644 (file)
@@ -1,3 +1,7 @@
+2021-01-07  Mike Frysinger  <vapier@gentoo.org>
+
+       * remote-sim.h (sim_memory_map): Define.
+
 2016-07-15  John Baldwin  <jhb@FreeBSD.org>
 
        * signals.def: Add GDB_SIGNAL_LIBRT.
index 73fb670c17e51efae2a0626d425b4651428539a5..a3ba3aa36cd2ec1fe310c629d2035da97cc92780 100644 (file)
@@ -213,6 +213,15 @@ int sim_store_register (SIM_DESC sd, int regno, unsigned char *buf, int length);
 void sim_info (SIM_DESC sd, int verbose);
 
 
+/* Return a memory map in XML format.
+
+   The caller must free the returned string.
+
+   For details on the format, see GDB's Memory Map Format documentation.  */
+
+char *sim_memory_map (SIM_DESC sd);
+
+
 /* Run (or resume) the simulated program.
 
    STEP, when non-zero indicates that only a single simulator cycle
index 0898a6f48eecd32d891d93cf5603ac6caf1f7ad6..05948f2fb31fd58b8f0ed9ba5663752a6f84c2c3 100644 (file)
@@ -1,3 +1,7 @@
+2021-01-07  Mike Frysinger  <vapier@gentoo.org>
+
+       * sim-core.c (sim_memory_map): Define.
+
 2021-01-04  Mike Frysinger  <vapier@gentoo.org>
 
        * acinclude.m4 (ACX_BUGURL): Change http:// to https://.
index 74369aa99fe2c04d494dfa1ac2205834e85518f5..538230635bc94421c842b07572e2db1ba737639f 100644 (file)
@@ -452,6 +452,63 @@ sim_core_translate (sim_core_mapping *mapping,
 }
 
 
+#if EXTERN_SIM_CORE_P
+/* See include/gdb/remote-sim.h.  */
+char *
+sim_memory_map (SIM_DESC sd)
+{
+  sim_core *core = STATE_CORE (sd);
+  unsigned map;
+  char *s1, *s2, *entry;
+
+  s1 = xstrdup (
+    "<?xml version='1.0'?>\n"
+    "<!DOCTYPE memory-map PUBLIC '+//IDN gnu.org//DTD GDB Memory Map V1.0//EN'"
+    " 'http://sourceware.org/gdb/gdb-memory-map.dtd'>\n"
+    "<memory-map>\n");
+
+  for (map = 0; map < nr_maps; ++map)
+    {
+      sim_core_mapping *mapping;
+
+      for (mapping = core->common.map[map].first;
+          mapping != NULL;
+          mapping = mapping->next)
+       {
+         /* GDB can only handle a single address space.  */
+         if (mapping->level != 0)
+           continue;
+
+         entry = xasprintf ("<memory type='ram' start='%#x' length='%#x'/>\n",
+                            mapping->base, mapping->nr_bytes);
+         /* The sim memory map is organized by access, not by addresses.
+            So a RWX memory map will have three independent mappings.
+            GDB's format cannot support overlapping regions, so we have
+            to filter those out.
+
+            Further, GDB can only handle RX ("rom") or RWX ("ram") mappings.
+            We just emit "ram" everywhere to keep it simple.  If GDB ever
+            gains support for more stuff, we can expand this.
+
+            Using strstr is kind of hacky, but as long as the map is not huge
+            (we're talking <10K), should be fine.  */
+         if (strstr (s1, entry) == NULL)
+           {
+             s2 = concat (s1, entry, NULL);
+             free (s1);
+             s1 = s2;
+           }
+         free (entry);
+       }
+    }
+
+  s2 = concat (s1, "</memory-map>", NULL);
+  free (s1);
+  return s2;
+}
+#endif
+
+
 #if EXTERN_SIM_CORE_P
 unsigned
 sim_core_read_buffer (SIM_DESC sd,