From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 18099 invoked by alias); 27 Feb 2012 18:04:53 -0000 Received: (qmail 18075 invoked by uid 22791); 27 Feb 2012 18:04:50 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,TW_EG X-Spam-Check-By: sourceware.org Received: from mail-qy0-f169.google.com (HELO mail-qy0-f169.google.com) (209.85.216.169) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 27 Feb 2012 18:04:35 +0000 Received: by qcsd16 with SMTP id d16so1949487qcs.0 for ; Mon, 27 Feb 2012 10:04:34 -0800 (PST) Received-SPF: pass (google.com: domain of hjl.tools@gmail.com designates 10.224.181.210 as permitted sender) client-ip=10.224.181.210; Authentication-Results: mr.google.com; spf=pass (google.com: domain of hjl.tools@gmail.com designates 10.224.181.210 as permitted sender) smtp.mail=hjl.tools@gmail.com; dkim=pass header.i=hjl.tools@gmail.com Received: from mr.google.com ([10.224.181.210]) by 10.224.181.210 with SMTP id bz18mr12665247qab.13.1330365874506 (num_hops = 1); Mon, 27 Feb 2012 10:04:34 -0800 (PST) MIME-Version: 1.0 Received: by 10.224.181.210 with SMTP id bz18mr10669167qab.13.1330365874438; Mon, 27 Feb 2012 10:04:34 -0800 (PST) Received: by 10.229.144.207 with HTTP; Mon, 27 Feb 2012 10:04:34 -0800 (PST) In-Reply-To: <4F21A489.2080200@redhat.com> References: <4F21A489.2080200@redhat.com> Date: Mon, 27 Feb 2012 18:49:00 -0000 Message-ID: Subject: Re: AVX and unavailable registers, fix system-gcore.exp From: "H.J. Lu" To: Pedro Alves Cc: GDB Patches , Mark Kettenis Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable 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: 2012-02/txt/msg00634.txt.bz2 On Thu, Jan 26, 2012 at 11:07 AM, Pedro Alves wrote: > I now have access to a machine with AVX, and I'm seeing a few core related > failures on native x86_64 Fedora 16. =A0GDBserver doesn't show the failur= es because > it treats this issue already like the patch below proposes. > > This was discussed a while ago, in the "RFC: partially available register= s" > thread: > > =A0http://old.nabble.com/RFC%3A-partially-available-registers-td32055573i= 20.html > > The failures I'm seeing look like, e.g.: > > FAIL: gdb.arch/system-gcore.exp: corefile restored all registers > > because before the core, the program showed: > > ... > ymm0 =A0 =A0 =A0 =A0 =A0 *value not available* > ... > > and when we load back the core we see: > > ... > ymm0 =A0 =A0 =A0 =A0 =A0 {v8_float =3D {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0= , 0x0}, v4_double =3D {0x0, 0x0, 0x0, 0x0}, v32_int8 =3D {0x0 s>}, v16_int16 =3D {0x0 }, v8_int32 =3D {0x0, 0x0, 0x0,= 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int64 =3D {0x0, 0x0, 0x0, 0x0}, v2_int > 128 =3D {0x00000000000000000000000000000000, 0x00000000000000000000000000= 000000}} > ... > > > I think we should make live debugging present the still-not-touched x87 > states as zero, as described in the comment in the patch: > > + =A0/* With the delayed xsave mechanism, in between the program > + =A0 =A0 starting, and the program accessing the vector registers for the > + =A0 =A0 first time, the register's values are invalid. =A0The kernel > + =A0 =A0 initializes register states to zero when they are set the first > + =A0 =A0 time in a program. =A0This means that from the user-space progr= ams' > + =A0 =A0 perspective, it's the same as if the registers have always been > + =A0 =A0 zero from the start of the program. =A0Therefore, the debugger > + =A0 =A0 should provide the same illusion to the user. > > This is already handled this way with gdbserver, hence we don't see > these failures there (the gcore tests now work against gdbserver). > The kernel is also putting the registers touched as zero > in the core, otherwise we'd see *unavailable* when we loaded the > core file back. > > > I have a doubt in the xsave-in-corefile support bits. =A0There's code in = place to > handle a NULL regs (as in no xsave contents to work with), so I'm handlin= g it > as presently: > > + > + =A0 =A0 Note however, the case when REGS is NULL is a different case. > + =A0 =A0 That case means we do not have access to the x87 states, so we > + =A0 =A0 should mark the registers as unavailable (by supplying NULL). = =A0*/ > + > > but I can't figure out how would we ever get a NULL REGS there. =A0Is the= re a > convoluted path I missed? =A0amd64-linux-tdep.c unconditionally installs > amd64_linux_regset_sections as gdbarch_core_regset_sections > callback, and this includes the .reg-xstate section. > However, corelow.c:get_core_register_section bails early if > a section is not found in the core, never reaching regset->supply_regset > with a NULL `contents'. > > Mark, maybe you have a clue? > > -- > Pedro Alves > > 2012-01-26 =A0Pedro Alves =A0 > > =A0 =A0 =A0 =A0* i387-tdep.c (i387_supply_xsave): If we have an xsave buf= fer, and > =A0 =A0 =A0 =A0the register state is clear, supply explicit zero, instead= of > =A0 =A0 =A0 =A0marking the register unavailable. This fixes 7.3/7.4 regression: http://www.sourceware.org/bugzilla/show_bug.cgi?id=3D13766 > --- > > =A0gdb/i387-tdep.c | =A0 87 ++++++++++++++++++++++++++++++++++-----------= ---------- > =A01 files changed, 54 insertions(+), 33 deletions(-) > > diff --git a/gdb/i387-tdep.c b/gdb/i387-tdep.c > index 450b8f2..b3adb74 100644 > --- a/gdb/i387-tdep.c > +++ b/gdb/i387-tdep.c > @@ -725,6 +725,7 @@ i387_supply_xsave (struct regcache *regcache, int reg= num, > =A0 const gdb_byte *regs =3D xsave; > =A0 int i; > =A0 unsigned int clear_bv; > + =A0const gdb_byte zero[MAX_REGISTER_SIZE] =3D { 0 }; Shouldn't it be static since it is never modified? > =A0 const gdb_byte *p; > =A0 enum > =A0 =A0 { > @@ -764,6 +765,19 @@ i387_supply_xsave (struct regcache *regcache, int re= gnum, > =A0 else > =A0 =A0 clear_bv =3D I386_XSTATE_AVX_MASK; > > + =A0/* With the delayed xsave mechanism, in between the program > + =A0 =A0 starting, and the program accessing the vector registers for the > + =A0 =A0 first time, the register's values are invalid. =A0The kernel > + =A0 =A0 initializes register states to zero when they are set the first > + =A0 =A0 time in a program. =A0This means that from the user-space progr= ams' > + =A0 =A0 perspective, it's the same as if the registers have always been > + =A0 =A0 zero from the start of the program. =A0Therefore, the debugger > + =A0 =A0 should provide the same illusion to the user. > + > + =A0 =A0 Note however, the case when REGS is NULL is a different case. > + =A0 =A0 That case means we do not have access to the x87 states, so we > + =A0 =A0 should mark the registers as unavailable (by supplying NULL). = =A0*/ > + > =A0 switch (regclass) > =A0 =A0 { > =A0 =A0 case none: > @@ -771,26 +785,26 @@ i387_supply_xsave (struct regcache *regcache, int r= egnum, > > =A0 =A0 case avxh: > =A0 =A0 =A0 if ((clear_bv & I386_XSTATE_AVX)) > - =A0 =A0 =A0 p =3D NULL; > + =A0 =A0 =A0 regcache_raw_supply (regcache, regnum, regs =3D=3D NULL ? N= ULL : zero); > =A0 =A0 =A0 else > - =A0 =A0 =A0 p =3D XSAVE_AVXH_ADDR (tdep, regs, regnum); > - =A0 =A0 =A0regcache_raw_supply (regcache, regnum, p); > + =A0 =A0 =A0 regcache_raw_supply (regcache, regnum, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0XSAVE_AVXH_ADDR = (tdep, regs, regnum)); > =A0 =A0 =A0 return; > > =A0 =A0 case sse: > =A0 =A0 =A0 if ((clear_bv & I386_XSTATE_SSE)) > - =A0 =A0 =A0 p =3D NULL; > + =A0 =A0 =A0 regcache_raw_supply (regcache, regnum, regs =3D=3D NULL ? N= ULL : zero); > =A0 =A0 =A0 else > - =A0 =A0 =A0 p =3D FXSAVE_ADDR (tdep, regs, regnum); > - =A0 =A0 =A0regcache_raw_supply (regcache, regnum, p); > + =A0 =A0 =A0 regcache_raw_supply (regcache, regnum, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0FXSAVE_ADDR (tde= p, regs, regnum)); > =A0 =A0 =A0 return; > > =A0 =A0 case x87: > =A0 =A0 =A0 if ((clear_bv & I386_XSTATE_X87)) > - =A0 =A0 =A0 p =3D NULL; > + =A0 =A0 =A0 regcache_raw_supply (regcache, regnum, regs =3D=3D NULL ? N= ULL : zero); > =A0 =A0 =A0 else > - =A0 =A0 =A0 p =3D FXSAVE_ADDR (tdep, regs, regnum); > - =A0 =A0 =A0regcache_raw_supply (regcache, regnum, p); > + =A0 =A0 =A0 regcache_raw_supply (regcache, regnum, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0FXSAVE_ADDR (tde= p, regs, regnum)); > =A0 =A0 =A0 return; > > =A0 =A0 case all: > @@ -798,16 +812,19 @@ i387_supply_xsave (struct regcache *regcache, int r= egnum, > =A0 =A0 =A0 if ((tdep->xcr0 & I386_XSTATE_AVX)) > =A0 =A0 =A0 =A0{ > =A0 =A0 =A0 =A0 =A0if ((clear_bv & I386_XSTATE_AVX)) > - =A0 =A0 =A0 =A0 =A0 p =3D NULL; > + =A0 =A0 =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 =A0 =A0 for (i =3D I387_YMM0H_REGNUM (tdep); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0i < I387_YMMENDH_REGNUM (tdep); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0i++) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 regcache_raw_supply (regcache, i, regs =3D= =3D NULL ? NULL : zero); > + =A0 =A0 =A0 =A0 =A0 } > =A0 =A0 =A0 =A0 =A0else > - =A0 =A0 =A0 =A0 =A0 p =3D regs; > - > - =A0 =A0 =A0 =A0 for (i =3D I387_YMM0H_REGNUM (tdep); > - =A0 =A0 =A0 =A0 =A0 =A0 =A0i < I387_YMMENDH_REGNUM (tdep); i++) > =A0 =A0 =A0 =A0 =A0 =A0{ > - =A0 =A0 =A0 =A0 =A0 =A0 if (p !=3D NULL) > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 p =3D XSAVE_AVXH_ADDR (tdep, regs, i); > - =A0 =A0 =A0 =A0 =A0 =A0 regcache_raw_supply (regcache, i, p); > + =A0 =A0 =A0 =A0 =A0 =A0 for (i =3D I387_YMM0H_REGNUM (tdep); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0i < I387_YMMENDH_REGNUM (tdep); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0i++) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 regcache_raw_supply (regcache, i, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= XSAVE_AVXH_ADDR (tdep, regs, i)); > =A0 =A0 =A0 =A0 =A0 =A0} > =A0 =A0 =A0 =A0} > > @@ -815,16 +832,18 @@ i387_supply_xsave (struct regcache *regcache, int r= egnum, > =A0 =A0 =A0 if ((tdep->xcr0 & I386_XSTATE_SSE)) > =A0 =A0 =A0 =A0{ > =A0 =A0 =A0 =A0 =A0if ((clear_bv & I386_XSTATE_SSE)) > - =A0 =A0 =A0 =A0 =A0 p =3D NULL; > + =A0 =A0 =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 =A0 =A0 for (i =3D I387_XMM0_REGNUM (tdep); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0i < I387_MXCSR_REGNUM (tdep); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0i++) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 regcache_raw_supply (regcache, i, regs =3D= =3D NULL ? NULL : zero); > + =A0 =A0 =A0 =A0 =A0 } > =A0 =A0 =A0 =A0 =A0else > - =A0 =A0 =A0 =A0 =A0 p =3D regs; > - > - =A0 =A0 =A0 =A0 for (i =3D I387_XMM0_REGNUM (tdep); > - =A0 =A0 =A0 =A0 =A0 =A0 =A0i < I387_MXCSR_REGNUM (tdep); i++) > =A0 =A0 =A0 =A0 =A0 =A0{ > - =A0 =A0 =A0 =A0 =A0 =A0 if (p !=3D NULL) > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 p =3D FXSAVE_ADDR (tdep, regs, i); > - =A0 =A0 =A0 =A0 =A0 =A0 regcache_raw_supply (regcache, i, p); > + =A0 =A0 =A0 =A0 =A0 =A0 for (i =3D I387_XMM0_REGNUM (tdep); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0i < I387_MXCSR_REGNUM (tdep); i++) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 regcache_raw_supply (regcache, i, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= FXSAVE_ADDR (tdep, regs, i)); > =A0 =A0 =A0 =A0 =A0 =A0} > =A0 =A0 =A0 =A0} > > @@ -832,16 +851,18 @@ i387_supply_xsave (struct regcache *regcache, int r= egnum, > =A0 =A0 =A0 if ((tdep->xcr0 & I386_XSTATE_X87)) > =A0 =A0 =A0 =A0{ > =A0 =A0 =A0 =A0 =A0if ((clear_bv & I386_XSTATE_X87)) > - =A0 =A0 =A0 =A0 =A0 p =3D NULL; > + =A0 =A0 =A0 =A0 =A0 { > + =A0 =A0 =A0 =A0 =A0 =A0 for (i =3D I387_ST0_REGNUM (tdep); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0i < I387_FCTRL_REGNUM (tdep); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0i++) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 regcache_raw_supply (regcache, i, regs !=3D= NULL ? zero : NULL); > + =A0 =A0 =A0 =A0 =A0 } > =A0 =A0 =A0 =A0 =A0else > - =A0 =A0 =A0 =A0 =A0 p =3D regs; > - > - =A0 =A0 =A0 =A0 for (i =3D I387_ST0_REGNUM (tdep); > - =A0 =A0 =A0 =A0 =A0 =A0 =A0i < I387_FCTRL_REGNUM (tdep); i++) > =A0 =A0 =A0 =A0 =A0 =A0{ > - =A0 =A0 =A0 =A0 =A0 =A0 if (p !=3D NULL) > - =A0 =A0 =A0 =A0 =A0 =A0 =A0 p =3D FXSAVE_ADDR (tdep, regs, i); > - =A0 =A0 =A0 =A0 =A0 =A0 regcache_raw_supply (regcache, i, p); > + =A0 =A0 =A0 =A0 =A0 =A0 for (i =3D I387_ST0_REGNUM (tdep); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0i < I387_FCTRL_REGNUM (tdep); > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0i++) > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 regcache_raw_supply (regcache, i, FXSAVE_AD= DR (tdep, regs, i)); > =A0 =A0 =A0 =A0 =A0 =A0} > =A0 =A0 =A0 =A0} > =A0 =A0 =A0 break; --=20 H.J.