Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: "H.J. Lu" <hjl.tools@gmail.com>
To: Pedro Alves <palves@redhat.com>
Cc: GDB Patches <gdb-patches@sourceware.org>,
	Mark Kettenis <mark.kettenis@xs4all.nl>
Subject: Re: AVX and unavailable registers, fix system-gcore.exp
Date: Mon, 27 Feb 2012 18:49:00 -0000	[thread overview]
Message-ID: <CAMe9rOp2x+pEJ5fcu5ipdQ=V-WwzQZp3zzZ83nCLiDQmihxMcA@mail.gmail.com> (raw)
In-Reply-To: <4F21A489.2080200@redhat.com>

On Thu, Jan 26, 2012 at 11:07 AM, Pedro Alves <palves@redhat.com> 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.  GDBserver doesn't show the failures because
> it treats this issue already like the patch below proposes.
>
> This was discussed a while ago, in the "RFC: partially available registers"
> thread:
>
>  http://old.nabble.com/RFC%3A-partially-available-registers-td32055573i20.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           *value not available*
> ...
>
> and when we load back the core we see:
>
> ...
> ymm0           {v8_float = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_double = {0x0, 0x0, 0x0, 0x0}, v32_int8 = {0x0 <repeats 32 time
> s>}, v16_int16 = {0x0 <repeats 16 times>}, v8_int32 = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, v4_int64 = {0x0, 0x0, 0x0, 0x0}, v2_int
> 128 = {0x00000000000000000000000000000000, 0x00000000000000000000000000000000}}
> ...
>
>
> I think we should make live debugging present the still-not-touched x87
> states as zero, as described in the comment in the patch:
>
> +  /* With the delayed xsave mechanism, in between the program
> +     starting, and the program accessing the vector registers for the
> +     first time, the register's values are invalid.  The kernel
> +     initializes register states to zero when they are set the first
> +     time in a program.  This means that from the user-space programs'
> +     perspective, it's the same as if the registers have always been
> +     zero from the start of the program.  Therefore, the debugger
> +     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.  There's code in place to
> handle a NULL regs (as in no xsave contents to work with), so I'm handling it
> as presently:
>
> +
> +     Note however, the case when REGS is NULL is a different case.
> +     That case means we do not have access to the x87 states, so we
> +     should mark the registers as unavailable (by supplying NULL).  */
> +
>
> but I can't figure out how would we ever get a NULL REGS there.  Is there a
> convoluted path I missed?  amd64-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  Pedro Alves  <palves@redhat.com>
>
>        * i387-tdep.c (i387_supply_xsave): If we have an xsave buffer, and
>        the register state is clear, supply explicit zero, instead of
>        marking the register unavailable.

This fixes 7.3/7.4 regression:

http://www.sourceware.org/bugzilla/show_bug.cgi?id=13766

> ---
>
>  gdb/i387-tdep.c |   87 ++++++++++++++++++++++++++++++++++---------------------
>  1 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 regnum,
>   const gdb_byte *regs = xsave;
>   int i;
>   unsigned int clear_bv;
> +  const gdb_byte zero[MAX_REGISTER_SIZE] = { 0 };

Shouldn't it be static since it is never modified?

>   const gdb_byte *p;
>   enum
>     {
> @@ -764,6 +765,19 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
>   else
>     clear_bv = I386_XSTATE_AVX_MASK;
>
> +  /* With the delayed xsave mechanism, in between the program
> +     starting, and the program accessing the vector registers for the
> +     first time, the register's values are invalid.  The kernel
> +     initializes register states to zero when they are set the first
> +     time in a program.  This means that from the user-space programs'
> +     perspective, it's the same as if the registers have always been
> +     zero from the start of the program.  Therefore, the debugger
> +     should provide the same illusion to the user.
> +
> +     Note however, the case when REGS is NULL is a different case.
> +     That case means we do not have access to the x87 states, so we
> +     should mark the registers as unavailable (by supplying NULL).  */
> +
>   switch (regclass)
>     {
>     case none:
> @@ -771,26 +785,26 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
>
>     case avxh:
>       if ((clear_bv & I386_XSTATE_AVX))
> -       p = NULL;
> +       regcache_raw_supply (regcache, regnum, regs == NULL ? NULL : zero);
>       else
> -       p = XSAVE_AVXH_ADDR (tdep, regs, regnum);
> -      regcache_raw_supply (regcache, regnum, p);
> +       regcache_raw_supply (regcache, regnum,
> +                            XSAVE_AVXH_ADDR (tdep, regs, regnum));
>       return;
>
>     case sse:
>       if ((clear_bv & I386_XSTATE_SSE))
> -       p = NULL;
> +       regcache_raw_supply (regcache, regnum, regs == NULL ? NULL : zero);
>       else
> -       p = FXSAVE_ADDR (tdep, regs, regnum);
> -      regcache_raw_supply (regcache, regnum, p);
> +       regcache_raw_supply (regcache, regnum,
> +                            FXSAVE_ADDR (tdep, regs, regnum));
>       return;
>
>     case x87:
>       if ((clear_bv & I386_XSTATE_X87))
> -       p = NULL;
> +       regcache_raw_supply (regcache, regnum, regs == NULL ? NULL : zero);
>       else
> -       p = FXSAVE_ADDR (tdep, regs, regnum);
> -      regcache_raw_supply (regcache, regnum, p);
> +       regcache_raw_supply (regcache, regnum,
> +                            FXSAVE_ADDR (tdep, regs, regnum));
>       return;
>
>     case all:
> @@ -798,16 +812,19 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
>       if ((tdep->xcr0 & I386_XSTATE_AVX))
>        {
>          if ((clear_bv & I386_XSTATE_AVX))
> -           p = NULL;
> +           {
> +             for (i = I387_YMM0H_REGNUM (tdep);
> +                  i < I387_YMMENDH_REGNUM (tdep);
> +                  i++)
> +               regcache_raw_supply (regcache, i, regs == NULL ? NULL : zero);
> +           }
>          else
> -           p = regs;
> -
> -         for (i = I387_YMM0H_REGNUM (tdep);
> -              i < I387_YMMENDH_REGNUM (tdep); i++)
>            {
> -             if (p != NULL)
> -               p = XSAVE_AVXH_ADDR (tdep, regs, i);
> -             regcache_raw_supply (regcache, i, p);
> +             for (i = I387_YMM0H_REGNUM (tdep);
> +                  i < I387_YMMENDH_REGNUM (tdep);
> +                  i++)
> +               regcache_raw_supply (regcache, i,
> +                                    XSAVE_AVXH_ADDR (tdep, regs, i));
>            }
>        }
>
> @@ -815,16 +832,18 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
>       if ((tdep->xcr0 & I386_XSTATE_SSE))
>        {
>          if ((clear_bv & I386_XSTATE_SSE))
> -           p = NULL;
> +           {
> +             for (i = I387_XMM0_REGNUM (tdep);
> +                  i < I387_MXCSR_REGNUM (tdep);
> +                  i++)
> +               regcache_raw_supply (regcache, i, regs == NULL ? NULL : zero);
> +           }
>          else
> -           p = regs;
> -
> -         for (i = I387_XMM0_REGNUM (tdep);
> -              i < I387_MXCSR_REGNUM (tdep); i++)
>            {
> -             if (p != NULL)
> -               p = FXSAVE_ADDR (tdep, regs, i);
> -             regcache_raw_supply (regcache, i, p);
> +             for (i = I387_XMM0_REGNUM (tdep);
> +                  i < I387_MXCSR_REGNUM (tdep); i++)
> +               regcache_raw_supply (regcache, i,
> +                                    FXSAVE_ADDR (tdep, regs, i));
>            }
>        }
>
> @@ -832,16 +851,18 @@ i387_supply_xsave (struct regcache *regcache, int regnum,
>       if ((tdep->xcr0 & I386_XSTATE_X87))
>        {
>          if ((clear_bv & I386_XSTATE_X87))
> -           p = NULL;
> +           {
> +             for (i = I387_ST0_REGNUM (tdep);
> +                  i < I387_FCTRL_REGNUM (tdep);
> +                  i++)
> +               regcache_raw_supply (regcache, i, regs != NULL ? zero : NULL);
> +           }
>          else
> -           p = regs;
> -
> -         for (i = I387_ST0_REGNUM (tdep);
> -              i < I387_FCTRL_REGNUM (tdep); i++)
>            {
> -             if (p != NULL)
> -               p = FXSAVE_ADDR (tdep, regs, i);
> -             regcache_raw_supply (regcache, i, p);
> +             for (i = I387_ST0_REGNUM (tdep);
> +                  i < I387_FCTRL_REGNUM (tdep);
> +                  i++)
> +               regcache_raw_supply (regcache, i, FXSAVE_ADDR (tdep, regs, i));
>            }
>        }
>       break;



-- 
H.J.


  reply	other threads:[~2012-02-27 18:04 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-01-26 19:16 Pedro Alves
2012-02-27 18:49 ` H.J. Lu [this message]
2012-02-27 19:23   ` Pedro Alves
2012-03-02 21:49     ` H.J. Lu
2012-03-05 14:24       ` Pedro Alves
2012-03-06 13:22         ` Pedro Alves
2012-03-05 14:32 ` i387-tdep.c:i387_supply_xsave: Assert the xsave section buffer, is not NULL Pedro Alves
2012-03-05 15:51   ` Mark Kettenis
2012-03-05 16:19     ` Pedro Alves

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAMe9rOp2x+pEJ5fcu5ipdQ=V-WwzQZp3zzZ83nCLiDQmihxMcA@mail.gmail.com' \
    --to=hjl.tools@gmail.com \
    --cc=gdb-patches@sourceware.org \
    --cc=mark.kettenis@xs4all.nl \
    --cc=palves@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox