summaryrefslogtreecommitdiff
path: root/gdb/value.c
diff options
context:
space:
mode:
authorAndrew Stubbs <andrew.stubbs@st.com>2006-03-31 10:36:18 +0000
committerAndrew Stubbs <andrew.stubbs@st.com>2006-03-31 10:36:18 +0000
commit3e3c6bfd41d9925260fba6cc04e6bbfe7ab0d4d0 (patch)
treec7f7747f4a765d4467caa8ec3d53a5e279536e2a /gdb/value.c
parentaa6be8b8574d4b14f26687d6930917ac02b66d63 (diff)
downloadgdb-3e3c6bfd41d9925260fba6cc04e6bbfe7ab0d4d0.tar.gz
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().
Diffstat (limited to 'gdb/value.c')
-rw-r--r--gdb/value.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/gdb/value.c b/gdb/value.c
index 2e304854bfa..77b92f6db7d 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -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)