[lldb-dev] Adding a new RegisterContext for Windows
Zachary Turner
zturner at google.com
Tue Nov 18 17:24:01 PST 2014
Sounds good.
One question. Why does each RegisterInfo need the array of kinds?
Wouldn't it be possible, in theory, to store a single integer here -- the
lldb register kind -- and then have an abstract interface which converts
from eRegisterKindLLDB to another arbitrary kind, and from some arbitrary
register kind to eRegisterKindLLDB? Then, there would be exactly one
implementation of this interface per CPU. So it would be independent of
the OS. Seems to me like no matter what OS you're on, EAX is still just
EAX. So even if there's some confusing stuff like ESP and EBP being mixed
up on old versions of GCC, that shouldn't have anything to do with the OS.
There's a lot of very similar sounding enums scattered around through the
existing RegisterContext files which leads to some confusion figuring out
what's what, and it seems like that would make the definitions of the
static arrays and register infos much simpler.
Not actually wanting to do something like that, just want make sure
understanding of the different register kinds and stuff is correct.
On Tue Nov 18 2014 at 4:43:50 PM Greg Clayton <gclayton at apple.com> wrote:
> I would be the best person to review it. Let me know when you have a patch.
>
> > On Nov 18, 2014, at 4:13 PM, Zachary Turner <zturner at google.com> wrote:
> >
> > Thanks.
> >
> > I'm working on a very not-fancy implementation for Windows. When I get
> it done, who would be the best person to take a look at it if I put up a
> review?
> >
> > Even if I'm the only person that understands the Windows-specific stuff,
> I think it would help to have someone familiar with these classes take a
> look at my implementation to make sure I've understood each of the
> functions correctly, and perhaps point out any gotchas that I might have
> fallen victim to or not be aware of.
> >
> > On Mon Nov 17 2014 at 5:01:02 PM Greg Clayton <gclayton at apple.com>
> wrote:
> >
> > > On Nov 17, 2014, at 3:59 PM, Zachary Turner <zturner at google.com>
> wrote:
> > >
> > > I'm looking into adding a new RegisterContext for windows. Virgile's
> patch that I was working on merging inherited from RegisterContext_POSIX,
> but on the surface this seems like the wrong thing to do, and I wonder if
> we need an entirely new one for Windows (or need to change the name of
> RegisterContext_POSIX to something else).
> > >
> > > What are all the steps involved here? From what I can tell at a
> minimum I need to implement a RegisterContextWindows_x86 and
> RegisterContextWindows_x86_64, but there's also RegisterInfoInterface and a
> few other things I need to figure out.
> > >
> > > A few other specific questions:
> > > 1) Why is all this stuff for different platforms is in
> Plugins/Process/Utility, instead of in the individual process plugins like
> Plugins/Process/Linux, or Plugins/Process/FreeBSD?
> >
> > These were being used by multiple plug-ins. FreeBSD and Linux are
> closely related (they use ptrace) so they can sometimes share their
> register contexts.
> >
> > >
> > > 2) Some code seems to be dead. Like in RegisterContextPosix, there's
> a long list of static variables, g_contained_eax, g_invalidate_eax, etc.
> But none of this stuff seems to be used for anything. Am I overlooking
> something obvious?
> >
> > If they are dead then remove them. Looking at the RegisterInfo struct:
> >
> > typedef struct
> > {
> > const char *name; // Name of this register, can't be NULL
> > const char *alt_name; // Alternate name of this register, can
> be NULL
> > uint32_t byte_size; // Size in bytes of the register
> > uint32_t byte_offset; // The byte offset in the register
> context data where this register's value is found
> > lldb::Encoding encoding; // Encoding of the register bits
> > lldb::Format format; // Default display format
> > uint32_t kinds[lldb::kNumRegisterKinds]; // Holds all of the
> various register numbers for all register kinds
> > uint32_t *value_regs; // List of registers that must be
> terminated with LLDB_INVALID_REGNUM
> > uint32_t *invalidate_regs; // List of registers that must be
> invalidated when this register is modified, list must be terminated with
> LLDB_INVALID_REGNUM
> > } RegisterInfo;
> >
> >
> > Registers can define registers that make up the value for this register
> (like "d0" on ARM can say it is made up from "s0" and "s1" since "d0" is a
> 64 bit register). Then this register is read from, it will not issue a
> register read for its own register number, but it will request all
> registers in "value_regs" be read instead.
> >
> > Likewise, you might want to invalidate registers when this register is
> modified, like "eax" (if you define one in your register context) would
> invalidate "rax" "ax" "al" if "eax" is modified.
> >
> > The static arrays seem to be left over from a copy and paste where
> g_contained_eax represented the register for "value_regs" or
> "invalidate_regs"...
> >
> > >
> > > 3) What is the difference between a RegisterInfoInterface and a
> RegisterContext?
> >
> > I am not sure, this class was implemented, but it isn't referenced
> currently.
> >
> > For register contexts you will just need to override all pure virtual
> functions in lldb_private::RegisterContext.
> >
> >
> > You must define all of your registers by returning a count:
> >
> > virtual size_t
> > RegisterContextWindows::GetRegisterCount () = 0;
> >
> > And supply a register info for each register. Register numbers are zero
> based index identifiers that must have no gaps. Each register must have a
> RegisterInfo struct that describes it:
> >
> > virtual const RegisterInfo *
> > RegisterContextWindows::GetRegisterInfoAtIndex (size_t reg) = 0;
> >
> >
> > You must also describe your register sets:
> >
> > virtual size_t
> > GetRegisterSetCount () = 0;
> >
> > virtual const RegisterSet *
> > GetRegisterSet (size_t reg_set) = 0;
> >
> > You must also be able to convert register numbers of various kinds into
> actual zero based register index IDs:
> >
> > virtual uint32_t
> > ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind,
> uint32_t num) = 0;
> >
> >
> > And read and write the registers (see all remaining pure virtuals).
> >
> > The common way to define your register infos is to just have a static
> array in your RegisterContextWindows.cpp:
> >
> > static RegisterInfo g_x86_64_register_infos[] =
> > {
> > ...
> > }
> >
> >
> > Then your RegisterContextWindows::GetRegisterInfoAtIndex() just returns
> >
> > const RegisterInfo *
> > RegisterContextWindows::GetRegisterInfoAtIndex (size_t reg)
> > {
> > if (reg < sizeof_array(g_x86_64_register_infos))
> > return g_x86_64_register_infos[reg];
> > return NULL;
> > }
> >
> > So there is nothing that special about the register context class, just
> implement the pure virtual and abstract it underneath so you have different
> classes for i386 and x86_64. The register context defines a bunch of bytes
> for all registers and the register info structs contain the byte_offset
> into the big data buffer that can contain all of your registers.
> >
> > Let me know if you have any questions.
> >
> > Greg
> >
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20141119/f551e92b/attachment.html>
More information about the lldb-dev
mailing list