This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFC] printing/setting flag register fields
- From: dje at google dot com (Doug Evans)
- To: gdb-patches at sourceware dot org
- Date: Fri, 18 Sep 2009 16:56:32 -0700 (PDT)
- Subject: [RFC] printing/setting flag register fields
Hi.
Before I go too far down this path, I'm looking for early feedback.
What do folks think?
(gdb) pty $eflags
type = builtin_type_i386_eflags
[ CF@0 PF@2 AF@4 ZF@6 SF@7 TF@8 IF@9 DF@10 OF@11 NT@14 RF@16 VM@17 AC@18 VIF@19 VIP@20 ID@21 ]
(gdb) p $eflags.CF
$1 = 0
(gdb) set $eflags.CF = 1
(gdb) p $eflags
$2 = [ CF PF ZF IF ]
(gdb) p/x $eflags
$3 = 0x247
(gdb) p $eflags.foo
There is no member named foo.
(gdb)
"pty $eflags" output is a bit hard to read, but I thought I'd play
with printing the field names *and* field positions.
If folks just want just the field names, ok.
And I need to add a wrap_here call to avoid running past
the column width.
Since this is an artificial type we can print it however we want,
I don't have much of a preference on the format.
Since "p $eflags" currently wraps the fields in [ ... ],
I chose to wrap the pty output similarily.
One improvement I like is to have append_flags_type_flag fill in
more stuff, so that TYPE_CODE_FLAGS types look more like other types.
Calling value_flags_elt from value_struct_elt feels clumsy,
but only mildly so. I can rewrite this however folks like.
[NEWS and docs elided for now, I'm just seeking feedback on the approach.]
2009-09-18 Doug Evans <dje@google.com>
Add support for printing and setting individual flag register fields.
* c-typeprint.c (c_type_print_varspec_prefix): Handle TYPE_CODE_FLAGS.
(c_type_print_varspec_suffix): Ditto.
(c_type_print_base): Ditto.
* valops.c (value_flags_elt): New function.
(value_struct_elt): Call it for TYPE_CODE_FLAGS types.
* value.c (value_flags_field): New function.
* value.h (value_flags_field): Declare it.
Index: c-typeprint.c
===================================================================
RCS file: /cvs/src/src/gdb/c-typeprint.c,v
retrieving revision 1.47
diff -u -p -r1.47 c-typeprint.c
--- c-typeprint.c 2 Jul 2009 12:57:14 -0000 1.47
+++ c-typeprint.c 18 Sep 2009 23:33:36 -0000
@@ -297,6 +297,7 @@ c_type_print_varspec_prefix (struct type
case TYPE_CODE_TEMPLATE:
case TYPE_CODE_NAMESPACE:
case TYPE_CODE_DECFLOAT:
+ case TYPE_CODE_FLAGS:
/* These types need no prefix. They are listed here so that
gcc -Wall will reveal any types that haven't been handled. */
break;
@@ -621,6 +622,7 @@ c_type_print_varspec_suffix (struct type
case TYPE_CODE_TEMPLATE:
case TYPE_CODE_NAMESPACE:
case TYPE_CODE_DECFLOAT:
+ case TYPE_CODE_FLAGS:
/* These types do not need a suffix. They are listed so that
gcc -Wall will report types that may not have been considered. */
break;
@@ -1149,6 +1151,30 @@ c_type_print_base (struct type *type, st
fputs_filtered (TYPE_TAG_NAME (type), stream);
break;
+ case TYPE_CODE_FLAGS:
+ c_type_print_modifier (type, stream, 0, 1);
+ fputs_filtered (TYPE_NAME (type), stream);
+ if (show < 0)
+ fprintf_filtered (stream, " [...]");
+ else if (show > 0)
+ {
+ wrap_here (" ");
+ fprintf_filtered (stream, " [");
+ len = TYPE_NFIELDS (type);
+ for (i = 0; i < len; ++i)
+ {
+ if (TYPE_FIELD_NAME (type, i) != NULL
+ && TYPE_FIELD_BITPOS (type, i) >= 0)
+ {
+ fputs_filtered (" ", stream);
+ fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
+ fprintf_filtered (stream, "@%d", TYPE_FIELD_BITPOS (type, i));
+ }
+ }
+ fprintf_filtered (stream, " ]");
+ }
+ break;
+
default:
/* Handle types not explicitly handled by the other cases,
such as fundamental types. For these, just print whatever
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.225
diff -u -p -r1.225 valops.c
--- valops.c 31 Aug 2009 20:18:45 -0000 1.225
+++ valops.c 18 Sep 2009 23:33:36 -0000
@@ -1799,6 +1799,27 @@ search_struct_method (char *name, struct
return NULL;
}
+/* Subroutine of value_struct_elt to simplify it.
+ Once we know we have a TYPE_CODE_FLAGS object,
+ extract the flag named NAME and return it as a value with its
+ appropriate type. */
+
+static struct value *
+value_flags_elt (struct type *type, struct value *flags, const char *name)
+{
+ int i;
+
+ for (i = 0; i < TYPE_NFIELDS (type); ++i)
+ {
+ const char *t_field_name = TYPE_FIELD_NAME (type, i);
+
+ if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
+ return value_flags_field (flags, i, type);
+ }
+
+ error (_("There is no member named %s."), name);
+}
+
/* Given *ARGP, a value of type (pointer to a)* structure/union,
extract the component named NAME from the ultimate target
structure/union and return it as a value with its appropriate type.
@@ -1836,6 +1857,9 @@ value_struct_elt (struct value **argp, s
t = check_typedef (value_type (*argp));
}
+ if (TYPE_CODE (t) == TYPE_CODE_FLAGS)
+ return value_flags_elt (t, *argp, name);
+
if (TYPE_CODE (t) != TYPE_CODE_STRUCT
&& TYPE_CODE (t) != TYPE_CODE_UNION)
error (_("Attempt to extract a component of a value that is not a %s."), err);
Index: value.c
===================================================================
RCS file: /cvs/src/src/gdb/value.c,v
retrieving revision 1.96
diff -u -p -r1.96 value.c
--- value.c 31 Aug 2009 20:18:45 -0000 1.96
+++ value.c 18 Sep 2009 23:33:36 -0000
@@ -1859,6 +1859,26 @@ value_change_enclosing_type (struct valu
return val;
}
+struct value *
+value_flags_field (struct value *arg1, int fieldno, struct type *arg_type)
+{
+ struct type *type = builtin_type (get_type_arch (arg_type))->builtin_unsigned_int;
+ struct value *v;
+
+ v = allocate_value_lazy (type);
+ v->bitsize = 1;
+ v->bitpos = TYPE_FIELD_BITPOS (arg_type, fieldno);
+ v->offset = 0;
+ v->parent = arg1;
+ value_incref (v->parent);
+ if (!value_lazy (arg1))
+ value_fetch_lazy (v);
+ set_value_component_location (v, arg1);
+ VALUE_REGNUM (v) = VALUE_REGNUM (arg1);
+ VALUE_FRAME_ID (v) = VALUE_FRAME_ID (arg1);
+ return v;
+}
+
/* Given a value ARG1 (offset by OFFSET bytes)
of a struct or union type ARG_TYPE,
extract and return the value of one of its (non-static) fields.
Index: value.h
===================================================================
RCS file: /cvs/src/src/gdb/value.h,v
retrieving revision 1.149
diff -u -p -r1.149 value.h
--- value.h 31 Aug 2009 20:18:45 -0000 1.149
+++ value.h 18 Sep 2009 23:33:36 -0000
@@ -451,13 +451,15 @@ extern int find_overload_match (struct t
struct value **valp, struct symbol **symp,
int *staticp);
+extern struct value *value_flags_field (struct value *arg1, int fieldno,
+ struct type *arg_type);
+
extern struct value *value_field (struct value *arg1, int fieldno);
extern struct value *value_primitive_field (struct value *arg1, int offset,
int fieldno,
struct type *arg_type);
-
extern struct type *value_rtti_target_type (struct value *, int *, int *,
int *);