2006-03-31 Andrew Stubbs <andrew.stubbs@st.com>
authorAndrew Stubbs <andrew.stubbs@st.com>
Fri, 31 Mar 2006 10:36:18 +0000 (10:36 +0000)
committerAndrew Stubbs <andrew.stubbs@st.com>
Fri, 31 Mar 2006 10:36:18 +0000 (10:36 +0000)
* value.h (struct internalvar): Add field 'endian'.
* value.c (lookup_internalvar): Initialise endian.
(value_of_internalvar): Flip the endian of built-in types if required.
(set_internalvar): Set the endian.
(show_convenience): Access the value through value_of_internalvar().

gdb/ChangeLog
gdb/value.c
gdb/value.h

index e581f7043193af93faca780342efddcc98b99d78..2409cacf4bcde2e9899fcc949c41528ec43a1941 100644 (file)
@@ -1,3 +1,11 @@
+2006-03-31  Andrew Stubbs  <andrew.stubbs@st.com>
+
+       * value.h (struct internalvar): Add field 'endian'.
+       * value.c (lookup_internalvar): Initialise endian.
+       (value_of_internalvar): Flip the endian of built-in types if required.
+       (set_internalvar): Set the endian.
+       (show_convenience): Access the value through value_of_internalvar().
+
 2006-03-30  Vladimir Prus  <ghost@cs.msu.su>
 
        * remote.c (watchpoint_to_Z_packet): Use values of Z_packet_type enum
index 2e304854bfadb48ebf355b2dcc7ceb9a7f5b6c8e..77b92f6db7d5b1af35ea04a52e1eaf2e576c83af 100644 (file)
@@ -755,6 +755,7 @@ lookup_internalvar (char *name)
   var = (struct internalvar *) xmalloc (sizeof (struct internalvar));
   var->name = concat (name, (char *)NULL);
   var->value = allocate_value (builtin_type_void);
+  var->endian = TARGET_BYTE_ORDER;
   release_value (var->value);
   var->next = internalvars;
   internalvars = var;
@@ -765,12 +766,46 @@ struct value *
 value_of_internalvar (struct internalvar *var)
 {
   struct value *val;
+  int i, j;
+  gdb_byte temp;
 
   val = value_copy (var->value);
   if (value_lazy (val))
     value_fetch_lazy (val);
   VALUE_LVAL (val) = lval_internalvar;
   VALUE_INTERNALVAR (val) = var;
+
+  /* Values are always stored in the target's byte order.  When connected to a
+     target this will most likely always be correct, so there's normally no
+     need to worry about it.
+
+     However, internal variables can be set up before the target endian is
+     known and so may become out of date.  Fix it up before anybody sees.
+
+     Internal variables usually hold simple scalar values, and we can
+     correct those.  More complex values (e.g. structures and floating
+     point types) are left alone, because they would be too complicated
+     to correct.  */
+
+  if (var->endian != TARGET_BYTE_ORDER)
+    {
+      gdb_byte *array = value_contents_raw (val);
+      struct type *type = check_typedef (value_enclosing_type (val));
+      switch (TYPE_CODE (type))
+       {
+       case TYPE_CODE_INT:
+       case TYPE_CODE_PTR:
+         /* Reverse the bytes.  */
+         for (i = 0, j = TYPE_LENGTH (type) - 1; i < j; i++, j--)
+           {
+             temp = array[j];
+             array[j] = array[i];
+             array[i] = temp;
+           }
+         break;
+       }
+    }
+
   return val;
 }
 
@@ -809,6 +844,7 @@ set_internalvar (struct internalvar *var, struct value *val)
      long.  */
   xfree (var->value);
   var->value = newval;
+  var->endian = TARGET_BYTE_ORDER;
   release_value (newval);
   /* End code which must not call error().  */
 }
@@ -877,7 +913,8 @@ show_convenience (char *ignore, int from_tty)
          varseen = 1;
        }
       printf_filtered (("$%s = "), var->name);
-      value_print (var->value, gdb_stdout, 0, Val_pretty_default);
+      value_print (value_of_internalvar (var), gdb_stdout,
+                  0, Val_pretty_default);
       printf_filtered (("\n"));
     }
   if (!varseen)
index e1972352270bacaca5de7ed58989d776f9ad475a..a878ec4008d48a28405338050670f7303f9805c1 100644 (file)
@@ -245,6 +245,7 @@ struct internalvar
   struct internalvar *next;
   char *name;
   struct value *value;
+  int endian;
 };
 
 \f