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 <ztur...@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 <gclay...@apple.com> wrote: > > > On Nov 17, 2014, at 3:59 PM, Zachary Turner <ztur...@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 > > _______________________________________________ lldb-dev mailing list lldb-dev@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev