[PATCH] gdb/sim: add support for exporting memory map
Andrew Burgess
andrew.burgess@embecosm.com
Wed Jan 6 09:49:20 GMT 2021
* Mike Frysinger via Gdb-patches <gdb-patches@sourceware.org> [2021-01-06 01:04:33 -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/remote-sim.c | 16 +++++++++++
> include/gdb/remote-sim.h | 9 +++++++
> sim/common/sim-core.c | 58 ++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 83 insertions(+)
>
> gdb/:
>
> * remote-sim.c: Include memory-map.h.
> (gdbsim_target): Define memory_map override.
> (gdbsim_target::memory_map): Define.
>
> include/gdb/:
>
> * remote-sim.h (sim_memory_map): Define.
>
> sim/common/:
>
> * sim-core.c (sim_memory_map): Define.
>
> diff --git a/gdb/remote-sim.c b/gdb/remote-sim.c
> index c4f3913edbad..e44add538afb 100644
> --- a/gdb/remote-sim.c
> +++ b/gdb/remote-sim.c
> @@ -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,20 @@ gdbsim_target::has_memory ()
> return true;
> }
>
> +std::vector<mem_region>
> +gdbsim_target::memory_map ()
This should have a header comment, even if its just:
/* Implement target_ops::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));
Whitespace missing after 'text'.
> +
> + if (text)
GDB prefers 'if (text != nullptr)'.
> + result = parse_memory_map (text.get ());
> +
> + return result;
> +}
> +
> void _initialize_remote_sim ();
> void
> _initialize_remote_sim ()
> diff --git a/include/gdb/remote-sim.h b/include/gdb/remote-sim.h
> index 73fb670c17e5..a3ba3aa36cd2 100644
> --- a/include/gdb/remote-sim.h
> +++ b/include/gdb/remote-sim.h
> @@ -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
> diff --git a/sim/common/sim-core.c b/sim/common/sim-core.c
> index 74369aa99fe2..eb40d2588f58 100644
> --- a/sim/common/sim-core.c
> +++ b/sim/common/sim-core.c
> @@ -452,6 +452,64 @@ sim_core_translate (sim_core_mapping *mapping,
> }
>
>
> +#if EXTERN_SIM_CORE_P
> +char *
> +sim_memory_map (SIM_DESC sd)
> +{
I would like to start following the GDB convention of requiring a
header comment on all functions, so here we'd just say:
/* See include/gdb/remote-sim.h. */
> + 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 = core->common.map[map].first;
> +
> + while (mapping != NULL)
Instead of using while here and then 'goto next' inside, could we not
say:
for (mapping = core->common.map[map].first;
mapping != NULL;
mapping = mapping->next)
and then replace the 'goto next' with 'continue' ?
> + {
> + if (mapping->level != 0)
> + goto next;
> +
> + 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);
> +
> + next:
> + mapping = mapping->next;
> + }
> + }
> +
> + s2 = concat (s1, "</memory-map>", NULL);
> + free (s1);
> + return s2;
> +}
> +#endif
> +
> +
> #if EXTERN_SIM_CORE_P
> unsigned
> sim_core_read_buffer (SIM_DESC sd,
> --
> 2.28.0
>
More information about the Gdb-patches
mailing list