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] 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 *);
 


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