Re: RFC: partially available registers

Pedro Alves
2011-07-26T16:07:58Z

On Tuesday 26 July 2011 16:31:18, Pedro Alves wrote:
> On Friday 22 July 2011 20:30:53, Tom Tromey wrote:
> > >>>>> "Pedro" == Pedro Alves <pedro@codesourcery.com> writes:
>
> > Pedro> But before the <unavailable> stuff, it meant "supply the register
> > Pedro> as 0". I seem to remember discussing this AVX stuff with H.J.,
> > Pedro> and coming to the conclusion that what want is really 0, but
> > Pedro> maybe not.
> >
> > I am far from being an expert in this area,
>
> Same here...
>
> > but from the Intel Architecture manual, section 13.5.1:
>
> Thanks. I finally took a bit to read that too.
>
> > Saving the x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 state using FXSAVE
> > requires processor overhead. If the new task does not access x87 FPU,
> > MMX, XMM, and MXCSR registers, avoid overhead by not automatically
> > saving the state on a task switch.
> >
> > The TS flag in control register CR0 is provided to allow the operating
> > system to delay saving the x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 state
> > until an instruction that actually accesses this state is encountered in
> > a new task.
> >
> > So I think what is going on here is that the upper bits of these
> > registers are truly unavailable, because the inferior has never executed
> > an instruction referencing them.
>
> My mental model of <unavailable> is:
>
> <unavailable> means the object exists, and its value exists,
> but we have no means to fetch it. This corresponds to trying
> to print the value of a register while inspecting a traceframe,
> while that register had not been collected by the corresponding
> tracepoint -- the register exists in the architecture/machine, but we
> can't know what value it had when the tracepoint hit. It also
> corresponds to a (trimmed/partial) core dump file not containing a
> dump of all the machine's registers, or a dump of all the process'es
> mapped memory (due to ulimit, perhaps). And corresponds to not
> being able to get at some register's current value because the
> debug API exposes no means to get at the current value. Along
> with other similar scenarios.
>
> Let me brain dump what I think is happening in this avx case,
> to make sure we're on the same page:
>
> In this case, IIUC, with the delayed xsave mechanism active,
> if a task has already accessed the x87 states, but hasn't triggered
> a delayed x87 states' save/restore since the last context switch, the
> current value of the x87 states of that task should be in the
> save area (and valie), which is what ptrace gives us when we read
> registers. For a task that did access (and change) the x87 state
> since the last x87 state save, (I hope!) a ptrace stopped task's
> save area is up to date with the real x87 states.

I glanced at:

<http://kerneltrap.org/mailarchive/linux-kernel/2010/2/10/4537101/thread>

and now I'm not sure my last assumption with ptrace stopped tasks
holds. If not, then we have two distinct cases to handle -- x87 state
has never been accessed; and x87 state in the xsave memory area is
not up to date. Is that true? Is there a way to distinguish them?
Is that what linux puts in the SW usable bytes [464..511]?

>
> That is, at runtime, the from ptrace's perpective, the delay/lazy
> scheme should be transparent, save for one case...
>
> ... that is the case of gdb/ptrace reading an x87 state
> before the program had first accessed the state itself for the
> first time.
>
> H.J.Lu wrote:
>
> > Values in vector registers are invalid, not unavailable. OS
> > initializes them to zero when they are set the firs time in
> > a program. I prefer *value not valid".
>
> That is, in between the program starting, and the program
> acessing the vector registers, the register's values are
> invalid. But, given that the kernel will fill them
> in with zero's on first access (meaning, from userspace's
> perspective, it's the same as if the registers have always
> been zero from the start of the program), I think it's best
> that a debugger provides the same illusion to the user.
>
> As H.J. wrote:
>
> > GDB may update vector registers before they are set by program.
> > GDB sets proper bits in XSAVE area to tell OS/hardware that vector
> > registers now have valid values.
>
> ... and indeed this is what i387-tdep.c:i387_collect_xsave
> appears to be doing.
>
> Am I making sense?
>
> > Pedro> Whatever the answer, we need to fix one of native
> > Pedro> gdb or gdbserver for consistency.
> >
> > If you agree with what I have checked in, I will update gdbserver.
>
> I think your patch implements the right interface for partial
> registers support. I like it...
>
> > Otherwise, let me know what you think would be correct and I will
> > implement that, instead, for both.
>
> ... but I think that we should go with 0, instead of <unavailable>,
> meaning changing x87-tdep.c:i387_supply_xsave to supply
> explicity zeroed buffer, instead of a NULL pointer, like
> gdbserver does.
>
>

--
Pedro Alves