This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] new MI command for pattern filling of memory regions


Hi all,

it's the first time I attempt a contribution to gdb, so feel free to ask for
details and, please, let me know if I'm doing anything wrong!

Short:
the proposed enhancement is about memory filling.

Rationale:
Filling a memory region with a pattern of bytes so far, can only be done by 
sending a potentially high number of repeated commands to gdb (depending on 
the size of the region that we need to fill).
If gdb is controlled through a GUI (e.g. Eclipse/CDT), this may cause the UI
to freeze for a quite long time. 
This is especially true when you're debugging a remote target, due to the
amount of generated network traffic.

Solution:
Implement an MI command that allows filling, with a specific pattern of bytes,
an arbitrarily sized memory region.

The proposed patch is here below, also including the related test script.

Regards,
	Giuseppe Montalto


From 9a168d60e69ce7618ab74591f230172554e4bc0b Mon Sep 17 00:00:00 2001
From: Giuseppe Montalto <giusepe.montalto@st.com>
Date: Wed, 9 May 2012 16:53:28 +0200
Subject: [PATCH] implemented a new MI command - data-fill-memory-bytes

---
 gdb/ChangeLog                           |    8 +++
 gdb/mi/mi-cmds.c                        |    1 +
 gdb/mi/mi-cmds.h                        |    1 +
 gdb/mi/mi-main.c                        |   73 +++++++++++++++++++++++++++++
 gdb/testsuite/ChangeLog                 |    4 ++
 gdb/testsuite/gdb.mi/mi-fill-memory.exp |   76 +++++++++++++++++++++++++++++++
 6 files changed, 163 insertions(+), 0 deletions(-)
 create mode 100644 gdb/testsuite/gdb.mi/mi-fill-memory.exp

diff --git gdb/ChangeLog gdb/ChangeLog
index 309473e..fe335bb 100644
--- gdb/ChangeLog
+++ gdb/ChangeLog
@@ -1,3 +1,11 @@
+2012-05-09  Giuseppe Montalto  <giuseppe.montalto@st.com>
+
+	* mi/mi-cmds.h (mi_cmd_data_fill_memory_bytes): New Declaration
+	* mi/mi-cmds.c (data-fill-memory-bytes): New member in struct 
+	mi_cmd mi_cmds
+	* mi/mi-main.c  (mi_cmd_data_fill_memory_bytes): new Function
+	implementation
+
 2012-05-09  Pedro Alves  <palves@redhat.com>
 
 	* target.c (set_maintenance_target_async_permitted): Rename to ...
diff --git gdb/mi/mi-cmds.c gdb/mi/mi-cmds.c
index 9152489..020a483 100644
--- gdb/mi/mi-cmds.c
+++ gdb/mi/mi-cmds.c
@@ -47,6 +47,7 @@ struct mi_cmd mi_cmds[] =
   { "break-watch", { NULL, 0 }, mi_cmd_break_watch},
   { "data-disassemble", { NULL, 0 }, mi_cmd_disassemble},
   { "data-evaluate-expression", { NULL, 0 }, mi_cmd_data_evaluate_expression},
+  { "data-fill-memory-bytes", {NULL, 0}, mi_cmd_data_fill_memory_bytes},
   { "data-list-changed-registers", { NULL, 0 },
     mi_cmd_data_list_changed_registers},
   { "data-list-register-names", { NULL, 0 }, mi_cmd_data_list_register_names},
diff --git gdb/mi/mi-cmds.h gdb/mi/mi-cmds.h
index c8465f0..7a8756b 100644
--- gdb/mi/mi-cmds.h
+++ gdb/mi/mi-cmds.h
@@ -45,6 +45,7 @@ extern mi_cmd_argv_ftype mi_cmd_break_passcount;
 extern mi_cmd_argv_ftype mi_cmd_break_watch;
 extern mi_cmd_argv_ftype mi_cmd_disassemble;
 extern mi_cmd_argv_ftype mi_cmd_data_evaluate_expression;
+extern mi_cmd_argv_ftype mi_cmd_data_fill_memory_bytes;
 extern mi_cmd_argv_ftype mi_cmd_data_list_register_names;
 extern mi_cmd_argv_ftype mi_cmd_data_list_register_values;
 extern mi_cmd_argv_ftype mi_cmd_data_list_changed_registers;
diff --git gdb/mi/mi-main.c gdb/mi/mi-main.c
index 90fb624..5d94333 100644
--- gdb/mi/mi-main.c
+++ gdb/mi/mi-main.c
@@ -1693,6 +1693,79 @@ mi_cmd_data_write_memory_bytes (char *command, char **argv, int argc)
   do_cleanups (back_to);
 }
 
+/* DATA-MEMORY-FILL-RAW:
+
+   ADDR: start address
+   COUNT: number of bytes to be filled (decimal integer)
+   DATA: string of bytes to write from that address. (1,2,4 or 8 bytes) */
+void
+mi_cmd_data_fill_memory_bytes (char *command, char **argv, int argc)
+{
+  CORE_ADDR addr;
+  char *cdata;
+  gdb_byte *data;
+  int len, r, i, steps;
+  long int count, j;
+  struct cleanup *back_to;
+
+  if (argc != 3)
+    error (_("Usage: ADDR COUNT DATA."));
+
+  /* read parameters */
+  addr = parse_and_eval_address (argv[0]);
+  /* COUNT is supposed to be a decimal integer*/
+  count = strtol(argv[1], NULL, 10);
+  cdata = argv[2];
+
+  /* calculate and allocate a memory buffer for DATA parameter */
+  len = strlen (cdata);
+  
+  if ( len != 2 && len != 4 && len != 8 && len != 16 )
+	    error (_("DATA must be 2, 4, 8 or 16 characters."));
+  
+  len = len/2;
+  
+  if ( (long int)len < count )
+    {
+	  /* pattern is made of less bytes than count: 
+	     repeat pattern to fill memory */
+	  data = xmalloc (count/len);
+	  back_to = make_cleanup (xfree, data);
+	
+	  steps = count/len;
+	  for (j = 0; j < steps; j++)
+		{
+		  for (i = 0; i < len; ++i)
+			{
+			  int x;
+			  sscanf (cdata + i * 2, "%02x", &x);
+			  data[i + j * len] = (gdb_byte)x;
+			}
+		}
+    }
+  else
+    {
+	  /* pattern is longer than (or equal to) count: 
+	     just copy len bytes */
+	  data = xmalloc (len);
+	  back_to = make_cleanup (xfree, data);
+	
+	  for (i = 0; i < len; ++i)
+		{
+		  int x;
+		  sscanf (cdata + i * 2, "%02x", &x);
+		  data[i] = (gdb_byte)x;
+		}
+    }
+
+  r = target_write_memory (addr, data, count);
+
+  if (r != 0)
+    error (_("Could not fill memory range with supplied pattern"));
+
+  do_cleanups (back_to);
+}
+
 void
 mi_cmd_enable_timings (char *command, char **argv, int argc)
 {
diff --git gdb/testsuite/ChangeLog gdb/testsuite/ChangeLog
index 43549bf..a49274f 100644
--- gdb/testsuite/ChangeLog
+++ gdb/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2012-05-09  Giuseppe Montalto  <giuseppe.montalto@st.com>
+
+	* gdb.mi/mi-fill-memory.exp: New test.
+
 2012-05-08  Maciej W. Rozycki  <macro@codesourcery.com>
 
 	* gdb.mi/mi-var-display.exp: Check for the existence of $fp
diff --git gdb/testsuite/gdb.mi/mi-fill-memory.exp gdb/testsuite/gdb.mi/mi-fill-memory.exp
new file mode 100644
index 0000000..40147e5
--- /dev/null
+++ gdb/testsuite/gdb.mi/mi-fill-memory.exp
@@ -0,0 +1,76 @@
+# Copyright (C) 2012 Free Software Foundation, Inc.
+# Copyright (C) 2012 STMicroelectronics
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#
+# test basic Machine interface (MI) operations
+#
+# Verify that, using the MI, we can load a program and do
+# other basic things that are used by all test files through  mi_gdb_exit,
+# mi_gdb_start, mi_delete_breakpoints, mi_gdb_reinitialize_dir and
+# mi_gdb_load, so we can safely use those.
+#
+# The goal is not to test gdb functionality, which is done by other tests,
+# but the command syntax and correct output response to MI operations.
+# 
+# added for testing the -data-fill-memory-bytes MI command
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi"
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile "mi-read-memory"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DFAKEARGV}] != "" } {
+     untested mi-read-memory.exp
+     return -1
+}
+
+
+mi_run_to_main
+mi_next_to "main" "" "mi-read-memory.c" "20" "next at main"
+
+mi_gdb_test "1-data-fill-memory-bytes" \
+	"1\\^error,msg=\"Usage: ADDR COUNT DATA\.\""\
+	"no arguments"
+
+mi_gdb_test "2-data-fill-memory-bytes 8" \
+	"2\\^error,msg=\"Usage: ADDR COUNT DATA\.\""\
+	"two arguments missing"
+
+mi_gdb_test "3-data-fill-memory-bytes 8 ab"\
+	"3\\^error,msg=\"Usage: ADDR COUNT DATA\.\""\
+	"one argument missing"
+
+mi_gdb_test "4-data-fill-memory-bytes \$pc 8 abc"\
+	"4\\^error,msg=\"DATA must be 2, 4, 8 or 16 characters\.\""\
+	"wrong data length"
+
+mi_gdb_test "5-data-fill-memory-bytes \$pc 8 ab"\
+	"5\\\^done" \
+	"memory successfully filled"
+
+mi_gdb_test "6-interpreter-exec console \"x \$pc\"" \
+    ".*0xabababab.*" \
+    "pattern correctly read from memory"
+
+mi_gdb_exit
+return 0
-- 
1.7.4.msysgit.0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]