From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4801 invoked by alias); 27 Aug 2002 21:40:39 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 4733 invoked from network); 27 Aug 2002 21:40:37 -0000 Received: from unknown (HELO localhost.redhat.com) (216.138.202.10) by sources.redhat.com with SMTP; 27 Aug 2002 21:40:37 -0000 Received: from ges.redhat.com (localhost [127.0.0.1]) by localhost.redhat.com (Postfix) with ESMTP id 5EE4E3C40; Tue, 27 Aug 2002 17:40:37 -0400 (EDT) Message-ID: <3D6BF1D5.70409@ges.redhat.com> Date: Tue, 27 Aug 2002 14:50:00 -0000 From: Andrew Cagney User-Agent: Mozilla/5.0 (X11; U; NetBSD macppc; en-US; rv:1.0.0) Gecko/20020824 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Michal Ludvig , gdb-patches@sources.redhat.com Subject: Re: [RFA] New bitflags type and eflags on i386/x86-64 References: <3CC42DA0.9070906@suse.cz> Content-Type: multipart/mixed; boundary="------------080106050205080104090801" X-SW-Source: 2002-08/txt/msg00914.txt.bz2 This is a multi-part message in MIME format. --------------080106050205080104090801 Content-Type: text/plain; charset=ISO-8859-2; format=flowed Content-Transfer-Encoding: 7bit Content-length: 833 Attatched is an old and related patch I've dug out of an old branch of GDB that Red Hat was providing for a customer. I don't actually care what the type of eflags ends up being (the attached looks like): (top-gdb) info registers .... eflags {eflags = 0x216, bits = {ID = 0x0, VIP = 0x0, VIF = 0x0, AC = 0x0, VM = 0x0, RF = 0x0, NT = 0x0, IOPL = 0x0, OF = 0x0, DF = 0x0, IF = 0x1, TF = 0x0, SF = 0x0, ZF = 0x0, AF = 0x1, PF = 0x1, CF = 0x0}} {eflags = 534, bits = {ID = 0, VIP = 0, VIF = 0, AC = 0, VM = 0, RF = 0, NT = 0, IOPL = 0, OF = 0, DF = 0, IF = 1, TF = 0, SF = 0, ZF = 0, AF = 1, PF = 1, CF = 0}} However, given that there are two implementations, I get the feeling that [possibly fee paying] users want something. Andrew (that reminds me, ``AC'' et.al. should be in lower case). --------------080106050205080104090801 Content-Type: text/plain; name="diffs" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="diffs" Content-length: 6430 2002-08-27 Andrew Cagney * i386-tdep.h (EFLAGS_REGNUM): Define. * i386-tdep.c (builtin_type_i386_eflags): New function. Based on code by Fernando Nasser. (i386_register_virtual_type): Return builtin_type_i386_eflags when EFLAGS_REGNUM. Index: i386-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/i386-tdep.c,v retrieving revision 1.83 diff -u -r1.83 i386-tdep.c --- i386-tdep.c 23 Aug 2002 19:26:14 -0000 1.83 +++ i386-tdep.c 27 Aug 2002 19:06:18 -0000 @@ -1090,6 +1090,174 @@ type); } +/* Construct some standard GDB types. */ + +static struct type * +builtin_type_i386_eflags (void) +{ + /* Construct a type for the EFLAGS register. The type we're + building is this: */ +#if 0 + union builtin_type_i386_eflags + { + int32_t eflags; + struct __builtin_i386_eflags_bits + { + /* We skip the 10 reserved bits here. */ + unsigned ID:1; + unsigned VIP:1; + unsigned VIF:1; + unsigned AC:1; + unsigned VM:1; + unsigned RF:1; + /* We skip one reserved bit here. */ + unsigned NT:1; + unsigned IOPL:2; + unsigned OF:1; + unsigned DF:1; + unsigned IF:1; + unsigned TF:1; + unsigned SF:1; + unsigned ZF:1; + /* We skip one reserved bit here. */ + unsigned AF:1; + /* We skip one reserved bit here. */ + unsigned PF:1; + /* We skip one reserved bit here. */ + unsigned CF:1; + } bits; + }; +#endif + /* Note that we cannot create a structure like that in C because we + could not skip the reserved bits and the order would be the + reverse of what we want (we want to see bit names from left to + right, as in a manual figure). */ + + static struct type *t; /* The type we are creating. */ + struct type *tp; /* The type of the pointer part. */ + struct type *tb; /* The type of the bitfields part. */ + struct field *fu; /* Fields of the union. */ + struct field *fs; /* Fields of the struct. */ + + if (t != NULL) + return t; + + /* Create fields for each group of bits. */ + fs = (struct field *) xmalloc (sizeof (*fs) * 17); + memset (fs, 0, sizeof (*fs) * 17); + + /* Note that we reverse the order of the fields so they are printed + as we would see then in a manual figure, left to right. */ + + FIELD_TYPE (fs[16]) = builtin_type_unsigned_int; + FIELD_NAME (fs[16]) = "CF"; + FIELD_BITPOS (fs[16]) = 0; + FIELD_BITSIZE (fs[16]) = 1; + + FIELD_TYPE (fs[15]) = builtin_type_unsigned_int; + FIELD_NAME (fs[15]) = "PF"; + FIELD_BITPOS (fs[15]) = 2; + FIELD_BITSIZE (fs[15]) = 1; + + FIELD_TYPE (fs[14]) = builtin_type_unsigned_int; + FIELD_NAME (fs[14]) = "AF"; + FIELD_BITPOS (fs[14]) = 4; + FIELD_BITSIZE (fs[14]) = 1; + + FIELD_TYPE (fs[13]) = builtin_type_unsigned_int; + FIELD_NAME (fs[13]) = "ZF"; + FIELD_BITPOS (fs[13]) = 6; + FIELD_BITSIZE (fs[13]) = 1; + + FIELD_TYPE (fs[12]) = builtin_type_unsigned_int; + FIELD_NAME (fs[12]) = "SF"; + FIELD_BITPOS (fs[12]) = 7; + FIELD_BITSIZE (fs[12]) = 1; + + FIELD_TYPE (fs[11]) = builtin_type_unsigned_int; + FIELD_NAME (fs[11]) = "TF"; + FIELD_BITPOS (fs[11]) = 8; + FIELD_BITSIZE (fs[11]) = 1; + + FIELD_TYPE (fs[10]) = builtin_type_unsigned_int; + FIELD_NAME (fs[10]) = "IF"; + FIELD_BITPOS (fs[10]) = 9; + FIELD_BITSIZE (fs[10]) = 1; + + FIELD_TYPE (fs[9]) = builtin_type_unsigned_int; + FIELD_NAME (fs[9]) = "DF"; + FIELD_BITPOS (fs[9]) = 10; + FIELD_BITSIZE (fs[9]) = 1; + + FIELD_TYPE (fs[8]) = builtin_type_unsigned_int; + FIELD_NAME (fs[8]) = "OF"; + FIELD_BITPOS (fs[8]) = 11; + FIELD_BITSIZE (fs[8]) = 1; + + FIELD_TYPE (fs[7]) = builtin_type_unsigned_int; + FIELD_NAME (fs[7]) = "IOPL"; + FIELD_BITPOS (fs[7]) = 12; + FIELD_BITSIZE (fs[7]) = 2; + + FIELD_TYPE (fs[6]) = builtin_type_unsigned_int; + FIELD_NAME (fs[6]) = "NT"; + FIELD_BITPOS (fs[6]) = 14; + FIELD_BITSIZE (fs[6]) = 1; + + FIELD_TYPE (fs[5]) = builtin_type_unsigned_int; + FIELD_NAME (fs[5]) = "RF"; + FIELD_BITPOS (fs[5]) = 16; + FIELD_BITSIZE (fs[5]) = 1; + + FIELD_TYPE (fs[4]) = builtin_type_unsigned_int; + FIELD_NAME (fs[4]) = "VM"; + FIELD_BITPOS (fs[4]) = 17; + FIELD_BITSIZE (fs[4]) = 1; + + FIELD_TYPE (fs[3]) = builtin_type_unsigned_int; + FIELD_NAME (fs[3]) = "AC"; + FIELD_BITPOS (fs[3]) = 18; + FIELD_BITSIZE (fs[3]) = 1; + + FIELD_TYPE (fs[2]) = builtin_type_unsigned_int; + FIELD_NAME (fs[2]) = "VIF"; + FIELD_BITPOS (fs[2]) = 19; + FIELD_BITSIZE (fs[2]) = 1; + + FIELD_TYPE (fs[1]) = builtin_type_unsigned_int; + FIELD_NAME (fs[1]) = "VIP"; + FIELD_BITPOS (fs[1]) = 20; + FIELD_BITSIZE (fs[1]) = 1; + + FIELD_TYPE (fs[0]) = builtin_type_unsigned_int; + FIELD_NAME (fs[0]) = "ID"; + FIELD_BITPOS (fs[0]) = 21; + FIELD_BITSIZE (fs[0]) = 1; + + /* Build a struct type with these bitfields. */ + tb = init_type (TYPE_CODE_STRUCT, 4, 0, 0, 0); + TYPE_NFIELDS (tb) = 17; + TYPE_FIELDS (tb) = fs; + TYPE_TAG_NAME (tb) = "builtin_type_i386_eflags_bits"; + + /* Now make our type as the union of the pointer and the bitfield parts. */ + fu = (struct field *) xmalloc (sizeof (*fu) * 2); + memset (fu, 0, sizeof (*fu) * 2); + + FIELD_TYPE (fu[0]) = builtin_type_int32; + FIELD_NAME (fu[0]) = "eflags"; + + FIELD_TYPE (fu[1]) = tb; + FIELD_NAME (fu[1]) = "bits"; + + /* Build a union type with those fields. */ + t = init_type (TYPE_CODE_UNION, 4, 0, 0, 0); + TYPE_NFIELDS (t) = 2; + TYPE_FIELDS (t) = fu; + TYPE_TAG_NAME (t) = "builtin_type_i386_eflags"; + + return t; +} /* Return the GDB type object for the "standard" data type of data in register REGNUM. Perhaps %esi and %edi should go here, but @@ -1100,6 +1268,9 @@ { if (regnum == PC_REGNUM || regnum == FP_REGNUM || regnum == SP_REGNUM) return lookup_pointer_type (builtin_type_void); + + if (regnum == EFLAGS_REGNUM) + return builtin_type_i386_eflags (); if (IS_FP_REGNUM (regnum)) return builtin_type_i387_ext; Index: i386-tdep.h =================================================================== RCS file: /cvs/src/src/gdb/i386-tdep.h,v retrieving revision 1.13 diff -u -r1.13 i386-tdep.h --- i386-tdep.h 20 Aug 2002 17:59:50 -0000 1.13 +++ i386-tdep.h 27 Aug 2002 19:06:18 -0000 @@ -77,6 +77,9 @@ int sc_sp_offset; }; +/* The EFLAGS register. */ +enum { EFLAGS_REGNUM = 9 }; + /* Floating-point registers. */ #define FPU_REG_RAW_SIZE 10 --------------080106050205080104090801 Content-Type: message/rfc822; name="mailbox-message://ac131313@movemail/fsf/gdb/patches/pending#139828" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="mailbox-message://ac131313@movemail/fsf/gdb/patches/pending#139828" Content-length: 12666 X-Mozilla-Status2: 10000000 Return-Path: Delivered-To: ac131313@localhost.redhat.com Received: from localhost (localhost [127.0.0.1]) by localhost.redhat.com (Postfix) with ESMTP id 034CA3D1A for ; Mon, 22 Apr 2002 11:39:50 -0400 (EDT) Received: from pop.cygnus.com by localhost with IMAP (fetchmail-5.9.6) for ac131313@localhost (single-drop); Mon, 22 Apr 2002 11:39:50 -0400 (EDT) Received: from cygnus-mx.sfbay.redhat.com (cygnus-mx.sfbay.redhat.com [172.16.27.16]) by runyon.cygnus.com (8.8.7-cygnus/8.8.7) with ESMTP id IAA25749 for ; Mon, 22 Apr 2002 08:35:12 -0700 (PDT) Received: from sources.redhat.com (sources.redhat.com [209.249.29.67]) by cygnus-mx.sfbay.redhat.com (8.11.6/8.11.6) with SMTP id g3M7h7J30881 for ; Mon, 22 Apr 2002 00:43:07 -0700 Received: (qmail 13653 invoked by alias); 22 Apr 2002 15:35:08 -0000 Received: (qmail 13630 invoked from network); 22 Apr 2002 15:35:05 -0000 Received: from unknown (HELO kerberos.suse.cz) (195.47.106.10) by sources.redhat.com with SMTP; 22 Apr 2002 15:35:05 -0000 Received: from chimera.suse.cz (chimera.suse.cz [10.20.0.2]) by kerberos.suse.cz (SuSE SMTP server) with ESMTP id 6F68C59D36F for ; Mon, 22 Apr 2002 17:35:04 +0200 (CEST) Received: from suse.cz (leviathan.suse.cz [10.20.1.56]) by chimera.suse.cz (8.11.0/8.11.0/SuSE Linux 8.11.0-0.4) with ESMTP id g3MFZ4f23728 for ; Mon, 22 Apr 2002 17:35:04 +0200 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Delivered-To: mailing list gdb-patches@sources.redhat.com X-Authentication-Warning: chimera.suse.cz: Host leviathan.suse.cz [10.20.1.56] claimed to be suse.cz Message-ID: <3CC42DA0.9070906@suse.cz> Date: Mon, 22 Apr 2002 17:34:56 +0200 From: Michal Ludvig Organization: SuSE CR User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0rc1) Gecko/20020417 X-Accept-Language: cs, cz, en MIME-Version: 1.0 To: gdb-patches@sources.redhat.com Subject: [RFA] New bitflags type and eflags on i386/x86-64 Content-Type: multipart/mixed; boundary="------------030302020401050602070203" This is a multi-part message in MIME format. --------------030302020401050602070203 Content-Type: text/plain; charset=ISO-8859-2; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1482 (Once again, now with Changelog :-) Hi all, I've created a new typecode TYPE_CODE_FLAGS with appropriate functions and used it in builtin_type_i386_eflags type. I did this to be able to print i386's and x86-64's FLAGS register in a symbolic form, instead of printing it in a hexadecimal and decimal notation. Now it looks like this: (gdb) info registers eflags eflags 0x747 [ DF IF TF ZF PF CF ] I've chosen quite a generic way for implementation, so that the others could use this for their types as well. For now I'm using this type only on x86-64, but using it on i386 should be possible without modifications. (BTW Should I do it or the maintainer will?) 2002-04-22 Michal Ludvig * c-valprint.c (c_val_print): Added handling of TYPE_CODE_FLAGS. * gdbtypes.c (builtin_type_i386_eflags): Added. (add_flag_ignore, add_flag_name, init_flags_type): Added. (is_integral_type, rank_one_type, recursive_dump_type): Added TYPE_CODE_FLAGS handling. (build_gdbtypes): Added builtin_type_i386_eflags initialization. * gdbtypes.h (type_code): Added TYPE_CODE_FLAGS. (builtin_type_i386_eflags): Added. * values.c (unpack_long: Added TYPE_CODE_FLAGS handling. * x86-64-tdep.c (x86_64_register_info_table): Changed type of eflags. Any comments? Can I commit? Michal Ludvig -- * SuSE CR, s.r.o * mludvig@suse.cz * +420 2 9654 5373 * http://www.suse.cz --------------030302020401050602070203 Content-Type: text/plain; name="eflags.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="eflags.diff" Content-length: 8136 Index: c-valprint.c =================================================================== RCS file: /cvs/src/src/gdb/c-valprint.c,v retrieving revision 1.13 diff -u -r1.13 c-valprint.c --- c-valprint.c 5 Feb 2002 21:41:29 -0000 1.13 +++ c-valprint.c 22 Apr 2002 14:50:12 -0000 @@ -70,6 +70,7 @@ int deref_ref, int recurse, enum val_prettyprint pretty) { register unsigned int i = 0; /* Number of characters printed */ + register int j; unsigned len; struct type *elttype; unsigned eltlen; @@ -483,6 +484,30 @@ TYPE_TARGET_TYPE (type), stream); fprintf_filtered (stream, " * I"); + break; + + case TYPE_CODE_FLAGS: + if (format) + { + print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); + break; + } + len = TYPE_NFIELDS (type); + val = unpack_long (type, valaddr + embedded_offset); + fputs_filtered("[", stream); + for (j = len-1; j >= 0; j--) + { + QUIT; + if (TYPE_FIELD_BITPOS (type, j) != -1 && val & (1 << j)) + { + if(TYPE_FIELD_NAME (type, j)) + fprintf_filtered (stream, " %s", TYPE_FIELD_NAME (type, j)); + else + fprintf_filtered (stream, " #%d", j); + + } + } + fputs_filtered(" ]", stream); break; default: Index: gdbtypes.c =================================================================== RCS file: /cvs/src/src/gdb/gdbtypes.c,v retrieving revision 1.43 diff -u -r1.43 gdbtypes.c --- gdbtypes.c 20 Apr 2002 01:09:28 -0000 1.43 +++ gdbtypes.c 22 Apr 2002 14:50:13 -0000 @@ -99,6 +99,7 @@ struct type *builtin_type_void_func_ptr; struct type *builtin_type_CORE_ADDR; struct type *builtin_type_bfd_vma; +struct type *builtin_type_i386_eflags; int opaque_type_resolution = 1; int overload_debug = 0; @@ -777,6 +778,67 @@ return (result_type); } +/* + * - The following three functions are intended to be used for BitFlags + * types (ie i386's EFLAGS register). + * - As a BitFlag we understand an integer where some bits may have + * a symbolic names that would be printed when the bit is set. + * - Printing is done in c_val_print() under a TYPE_CODE_FLAGS label. + * - All bits are set to be ignored (ie. not printed even when set) + * by default. + * - Add a symbolic name of relevant bits using add_flag_name() after + * an initialisation of your type. + */ +void +add_flag_ignore (struct type *type, int bitpos) +{ + TYPE_FIELD_BITPOS (type, bitpos) = -1; +} + +void +add_flag_name (struct type *type, int bitpos, char *name) +{ + int namelen; + + gdb_assert (TYPE_CODE (type) == TYPE_CODE_FLAGS); + gdb_assert (bitpos < TYPE_NFIELDS (type)); + gdb_assert (bitpos >= 0); + + namelen=strlen(name)+1; + TYPE_FIELD_NAME (type, bitpos) = xmalloc (namelen); + snprintf(TYPE_FIELD_NAME (type, bitpos), namelen, "%s", name); + + TYPE_FIELD_BITPOS (type, bitpos) = bitpos; +} + +struct type * +init_flags_type (int bitlength, char *name, struct objfile *objfile) +{ + register struct type *type; + int i; + + type = alloc_type (objfile); + + TYPE_CODE (type) = TYPE_CODE_FLAGS; + TYPE_LENGTH (type) = bitlength / 8 + ( bitlength % 8 ? 1 : 0 ); + TYPE_FLAGS (type) = TYPE_FLAG_UNSIGNED; + TYPE_NFIELDS (type) = bitlength; + TYPE_FIELDS (type) = (struct field *) + TYPE_ALLOC (type, bitlength * sizeof (struct field)); + memset (TYPE_FIELDS (type), 0, sizeof (struct field)); + + if ((name != NULL) && (objfile != NULL)) + TYPE_NAME (type) = + obsavestring (name, strlen (name), &objfile->type_obstack); + else + TYPE_NAME (type) = name; + + for(i=0; i