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]

RFC: fix `gdb -write' case


I'd appreciate comments on this.  In the absence of comments I will
check it in.  I plan to put it on the 7.3 branch as well.

This comes from:

    https://bugzilla.redhat.com/show_bug.cgi?id=696148

The bug is that you cannot change a string in an executable with `gdb
-write'.  Jan tracked this down to the wide string change; the bug is
that evaluate_subexp_c did not examine `expect_type', leading to an
attempt to coerce the string to memory.

Built and regtested by our internal buildbot.

Tom

2011-05-06  Tom Tromey  <tromey@redhat.com>

	* c-lang.c (evaluate_subexp_c): Use expect_type if it is not
	NULL.

diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index ad770bf..64c4d79 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -1061,9 +1061,39 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp,
 	    /* Write the terminating character.  */
 	    for (i = 0; i < TYPE_LENGTH (type); ++i)
 	      obstack_1grow (&output, 0);
-	    result = value_cstring (obstack_base (&output),
-				    obstack_object_size (&output),
-				    type);
+
+	    if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_ARRAY)
+	      {
+		LONGEST low_bound, high_bound;
+		struct type *element_type
+		  = check_typedef (TYPE_TARGET_TYPE (expect_type));
+		int element_size = TYPE_LENGTH (element_type);
+
+		if (TYPE_CODE (element_type) != TYPE_CODE_INT
+		    && (TYPE_CODE (element_type) != TYPE_CODE_CHAR))
+		  error (_("wrong expected type for string constant"));
+		if (TYPE_LENGTH (element_type) != TYPE_LENGTH (type))
+		  error (_("expected type of string constant has wrong "
+			   "character width"));
+
+		if (get_discrete_bounds (TYPE_INDEX_TYPE (expect_type),
+					 &low_bound, &high_bound) < 0)
+		  {
+		    low_bound = 0;
+		    high_bound = (TYPE_LENGTH (expect_type) / element_size) - 1;
+		  }
+		if (obstack_object_size (&output) / TYPE_LENGTH (type)
+		    > (high_bound - low_bound + 1))
+		  error (_("Too many array elements"));
+
+		result = allocate_value (expect_type);
+		memcpy (value_contents_raw (result), obstack_base (&output),
+			obstack_object_size (&output));
+	      }
+	    else
+	      result = value_cstring (obstack_base (&output),
+				      obstack_object_size (&output),
+				      type);
 	  }
 	do_cleanups (cleanup);
 	return result;


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