From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23515 invoked by alias); 18 Sep 2009 23:57:12 -0000 Received: (qmail 23501 invoked by uid 22791); 18 Sep 2009 23:57:11 -0000 X-SWARE-Spam-Status: No, hits=-2.1 required=5.0 tests=AWL,BAYES_00,SPF_PASS X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.45.13) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 18 Sep 2009 23:56:36 +0000 Received: from wpaz21.hot.corp.google.com (wpaz21.hot.corp.google.com [172.24.198.85]) by smtp-out.google.com with ESMTP id n8INuYu7002732 for ; Fri, 18 Sep 2009 16:56:34 -0700 Received: from ruffy.mtv.corp.google.com (ruffy.mtv.corp.google.com [172.18.118.116]) by wpaz21.hot.corp.google.com with ESMTP id n8INuWuX028102 for ; Fri, 18 Sep 2009 16:56:32 -0700 Received: by ruffy.mtv.corp.google.com (Postfix, from userid 67641) id 0DDC6843AC; Fri, 18 Sep 2009 16:56:32 -0700 (PDT) To: gdb-patches@sourceware.org Subject: [RFC] printing/setting flag register fields Message-Id: <20090918235632.0DDC6843AC@ruffy.mtv.corp.google.com> Date: Fri, 18 Sep 2009 23:57:00 -0000 From: dje@google.com (Doug Evans) X-System-Of-Record: true X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-09/txt/msg00618.txt.bz2 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 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 *);