From d3c139e92615d7029c6b34c0ae68e02b54571a98 Mon Sep 17 00:00:00 2001 From: Andrew Stubbs Date: Fri, 31 Mar 2006 10:36:18 +0000 Subject: [PATCH] 2006-03-31 Andrew Stubbs * 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 | 8 ++++++++ gdb/value.c | 39 ++++++++++++++++++++++++++++++++++++++- gdb/value.h | 1 + 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e581f704319..2409cacf4bc 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2006-03-31 Andrew Stubbs + + * 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 * remote.c (watchpoint_to_Z_packet): Use values of Z_packet_type enum 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) diff --git a/gdb/value.h b/gdb/value.h index e1972352270..a878ec4008d 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -245,6 +245,7 @@ struct internalvar struct internalvar *next; char *name; struct value *value; + int endian; }; -- 2.39.2