[Lldb-commits] x86_32 linux support
Stephen Wilson
wilsons at start.ca
Mon Feb 28 15:02:22 PST 2011
On Mon, Feb 28, 2011 at 11:30:48AM -0800, Greg Clayton wrote:
>
> On Feb 26, 2011, at 1:58 PM, Stephen Wilson wrote:
>
> > Marco, Greg,
> >
> > On Sat, Feb 26, 2011 at 03:09:45PM +0100, Marco Minutoli wrote:
> >> Here is the patch with the changes you have requested.
> >
> > Nice. This looks good.
> >
> >
> > Greg, mind if I commit this one? There is one trivial tweak needed to
> > avoid a compile time warning.
>
> I am happy with letting you OK the any linux specific patches. If it
> touches anyting in the core that is significant, then let me know,
> else I will let you OK the linux patches, is that alright?
OK. That sounds good to me. Of course, I will always appreciate any
review/suggestions of the linux specific stuff post-commit.
Committed in r126696.
> >
> >> Sorry for the duplicated header here It was late night(or maybe early
> >> in the morning :D) when I sent the patch to the ML. Next time I'll be
> >> more careful.
> >
> > No worries! We still have a bit of work to do to support i386 on linux
> > but this is a significant step forward. Thanks so much!
> >
> >
> >> Best regards,
> >> Marco
> >>
> >> On Sat, Feb 26, 2011 at 1:25 AM, Stephen Wilson <wilsons at start.ca> wrote:
> >>> On Fri, Feb 25, 2011 at 02:52:51AM +0100, Marco Minutoli wrote:
> >>>> Hi everybody,
> >>>>
> >>>> as suggested by Stephen I had a look at the user_32.h Linux header and
> >>>> I fixed the UserArea structure.
> >>>>
> >>>> In the attachment the revised patch. As ever comments and suggestions
> >>>> are welcome :).
> >>>
> >>> This looks good. Only two small issues: the patch for
> >>> RegisterContextLinux_i386.h contains the old and new versions of your
> >>> patch (the latter is protected behind an #ifndef). Also, I think we
> >>> need the following patch for LinuxThread.cpp: Use a register context
> >>> according to the host instead of the process target so we can debug and
> >>> test lldb using 32-bit binaries on 64-bit systems.
> >>>
> >>> I have not been able to test your patch much yet -- another issue has
> >>> crept into the linux builds that I need to track down first... but with
> >>> those changes I think the patches can go in.
> >>>
> >>>
> >>>
> >>> Thanks again!
> >>>
> >>>
> >>> diff --git a/source/Plugins/Process/Linux/LinuxThread.cpp b/source/Plugins/Process/Linux/LinuxThread.cpp
> >>> index 397d31b..15bc9e3 100644
> >>> --- a/source/Plugins/Process/Linux/LinuxThread.cpp
> >>> +++ b/source/Plugins/Process/Linux/LinuxThread.cpp
> >>> @@ -12,6 +12,7 @@
> >>>
> >>> // C++ Includes
> >>> // Other libraries and framework includes
> >>> +#include "lldb/Host/Host.h"
> >>> #include "lldb/Target/Process.h"
> >>> #include "lldb/Target/StopInfo.h"
> >>> #include "lldb/Target/Target.h"
> >>> @@ -19,6 +20,7 @@
> >>> #include "LinuxThread.h"
> >>> #include "ProcessLinux.h"
> >>> #include "ProcessMonitor.h"
> >>> +#include "RegisterContextLinux_i386.h"
> >>> #include "RegisterContextLinux_x86_64.h"
> >>> #include "UnwindLLDB.h"
> >>>
> >>> @@ -59,11 +61,9 @@ LinuxThread::GetInfo()
> >>> lldb::RegisterContextSP
> >>> LinuxThread::GetRegisterContext()
> >>> {
> >>> - ProcessLinux &process = static_cast<ProcessLinux&>(GetProcess());
> >>> -
> >>> if (!m_reg_context_sp)
> >>> {
> >>> - ArchSpec arch = process.GetTarget().GetArchitecture();
> >>> + ArchSpec arch = Host::GetArchitecture();
> >>>
> >>> switch (arch.GetCore())
> >>> {
> >>> @@ -71,6 +71,12 @@ LinuxThread::GetRegisterContext()
> >>> assert(false && "CPU type not supported!");
> >>> break;
> >>>
> >>> + case ArchSpec::eCore_x86_32_i386:
> >>> + case ArchSpec::eCore_x86_32_i486:
> >>> + case ArchSpec::eCore_x86_32_i486sx:
> >>> + m_reg_context_sp.reset(new RegisterContextLinux_i386(*this, 0));
> >>> + break;
> >>> +
> >>> case ArchSpec::eCore_x86_64_x86_64:
> >>> m_reg_context_sp.reset(new RegisterContextLinux_x86_64(*this, 0));
> >>> break;
> >>>
> >>
> >>
> >>
> >> --
> >> Marco Minutoli
> >>
> >> "If A is success in life, then A equals x plus y plus z. Work is x;
> >> y is play; and z is keeping your mouth shut." --A. Einstein
> >
> >> diff --git a/source/Plugins/Process/Linux/LinuxThread.cpp b/source/Plugins/Process/Linux/LinuxThread.cpp
> >> index 397d31b..8f3a273 100644
> >> --- a/source/Plugins/Process/Linux/LinuxThread.cpp
> >> +++ b/source/Plugins/Process/Linux/LinuxThread.cpp
> >> @@ -12,6 +12,7 @@
> >>
> >> // C++ Includes
> >> // Other libraries and framework includes
> >> +#include "lldb/Host/Host.h"
> >> #include "lldb/Target/Process.h"
> >> #include "lldb/Target/StopInfo.h"
> >> #include "lldb/Target/Target.h"
> >> @@ -19,6 +20,7 @@
> >> #include "LinuxThread.h"
> >> #include "ProcessLinux.h"
> >> #include "ProcessMonitor.h"
> >> +#include "RegisterContextLinux_i386.h"
> >> #include "RegisterContextLinux_x86_64.h"
> >> #include "UnwindLLDB.h"
> >>
> >> @@ -63,7 +65,7 @@ LinuxThread::GetRegisterContext()
> >>
> >> if (!m_reg_context_sp)
> >> {
> >> - ArchSpec arch = process.GetTarget().GetArchitecture();
> >> + ArchSpec arch = Host::GetArchitecture();
> >>
> >> switch (arch.GetCore())
> >> {
> >> @@ -71,6 +73,12 @@ LinuxThread::GetRegisterContext()
> >> assert(false && "CPU type not supported!");
> >> break;
> >>
> >> + case ArchSpec::eCore_x86_32_i386:
> >> + case ArchSpec::eCore_x86_32_i486:
> >> + case ArchSpec::eCore_x86_32_i486sx:
> >> + m_reg_context_sp.reset(new RegisterContextLinux_i386(*this, 0));
> >> + break;
> >> +
> >> case ArchSpec::eCore_x86_64_x86_64:
> >> m_reg_context_sp.reset(new RegisterContextLinux_x86_64(*this, 0));
> >> break;
> >> diff --git a/source/Plugins/Process/Linux/RegisterContextLinux_i386.cpp b/source/Plugins/Process/Linux/RegisterContextLinux_i386.cpp
> >> new file mode 100644
> >> index 0000000..b7451d2
> >> --- /dev/null
> >> +++ b/source/Plugins/Process/Linux/RegisterContextLinux_i386.cpp
> >> @@ -0,0 +1,633 @@
> >> +//===-- RegisterContextLinux_i386.cpp ----------------------------*- C++ -*-===//
> >> +//
> >> +// The LLVM Compiler Infrastructure
> >> +//
> >> +// This file is distributed under the University of Illinois Open Source
> >> +// License. See LICENSE.TXT for details.
> >> +//
> >> +//===----------------------------------------------------------------------===//
> >> +
> >> +#include "lldb/Core/DataExtractor.h"
> >> +#include "lldb/Target/Thread.h"
> >> +#include "lldb/Host/Endian.h"
> >> +
> >> +#include "ProcessLinux.h"
> >> +#include "ProcessMonitor.h"
> >> +#include "RegisterContextLinux_i386.h"
> >> +
> >> +using namespace lldb_private;
> >> +using namespace lldb;
> >> +
> >> +enum
> >> +{
> >> + k_first_gpr,
> >> + gpr_eax = k_first_gpr,
> >> + gpr_ebx,
> >> + gpr_ecx,
> >> + gpr_edx,
> >> + gpr_edi,
> >> + gpr_esi,
> >> + gpr_ebp,
> >> + gpr_esp,
> >> + gpr_ss,
> >> + gpr_eflags,
> >> + gpr_orig_ax,
> >> + gpr_eip,
> >> + gpr_cs,
> >> + gpr_ds,
> >> + gpr_es,
> >> + gpr_fs,
> >> + gpr_gs,
> >> + k_last_gpr = gpr_gs,
> >> +
> >> + k_first_fpr,
> >> + fpu_fcw = k_first_fpr,
> >> + fpu_fsw,
> >> + fpu_ftw,
> >> + fpu_fop,
> >> + fpu_ip,
> >> + fpu_cs,
> >> + fpu_foo,
> >> + fpu_fos,
> >> + fpu_mxcsr,
> >> + fpu_stmm0,
> >> + fpu_stmm1,
> >> + fpu_stmm2,
> >> + fpu_stmm3,
> >> + fpu_stmm4,
> >> + fpu_stmm5,
> >> + fpu_stmm6,
> >> + fpu_stmm7,
> >> + fpu_xmm0,
> >> + fpu_xmm1,
> >> + fpu_xmm2,
> >> + fpu_xmm3,
> >> + fpu_xmm4,
> >> + fpu_xmm5,
> >> + fpu_xmm6,
> >> + fpu_xmm7,
> >> + k_last_fpr = fpu_xmm7,
> >> +
> >> + k_num_registers,
> >> + k_num_gpr_registers = k_last_gpr - k_first_gpr + 1,
> >> + k_num_fpu_registers = k_last_fpr - k_first_fpr + 1
> >> +};
> >> +
> >> +// Number of register sets provided by this context.
> >> +enum
> >> +{
> >> + k_num_register_sets = 2
> >> +};
> >> +
> >> +enum
> >> +{
> >> + gcc_eax = 0,
> >> + gcc_ecx,
> >> + gcc_edx,
> >> + gcc_ebx,
> >> + gcc_ebp,
> >> + gcc_esp,
> >> + gcc_esi,
> >> + gcc_edi,
> >> + gcc_eip,
> >> + gcc_eflags
> >> +};
> >> +
> >> +enum
> >> +{
> >> + dwarf_eax = 0,
> >> + dwarf_ecx,
> >> + dwarf_edx,
> >> + dwarf_ebx,
> >> + dwarf_esp,
> >> + dwarf_ebp,
> >> + dwarf_esi,
> >> + dwarf_edi,
> >> + dwarf_eip,
> >> + dwarf_eflags,
> >> + dwarf_stmm0 = 11,
> >> + dwarf_stmm1,
> >> + dwarf_stmm2,
> >> + dwarf_stmm3,
> >> + dwarf_stmm4,
> >> + dwarf_stmm5,
> >> + dwarf_stmm6,
> >> + dwarf_stmm7,
> >> + dwarf_xmm0 = 21,
> >> + dwarf_xmm1,
> >> + dwarf_xmm2,
> >> + dwarf_xmm3,
> >> + dwarf_xmm4,
> >> + dwarf_xmm5,
> >> + dwarf_xmm6,
> >> + dwarf_xmm7
> >> +};
> >> +
> >> +enum
> >> +{
> >> + gdb_eax = 0,
> >> + gdb_ecx = 1,
> >> + gdb_edx = 2,
> >> + gdb_ebx = 3,
> >> + gdb_esp = 4,
> >> + gdb_ebp = 5,
> >> + gdb_esi = 6,
> >> + gdb_edi = 7,
> >> + gdb_eip = 8,
> >> + gdb_eflags = 9,
> >> + gdb_cs = 10,
> >> + gdb_ss = 11,
> >> + gdb_ds = 12,
> >> + gdb_es = 13,
> >> + gdb_fs = 14,
> >> + gdb_gs = 15,
> >> + gdb_stmm0 = 16,
> >> + gdb_stmm1 = 17,
> >> + gdb_stmm2 = 18,
> >> + gdb_stmm3 = 19,
> >> + gdb_stmm4 = 20,
> >> + gdb_stmm5 = 21,
> >> + gdb_stmm6 = 22,
> >> + gdb_stmm7 = 23,
> >> + gdb_fcw = 24,
> >> + gdb_fsw = 25,
> >> + gdb_ftw = 26,
> >> + gdb_fpu_cs = 27,
> >> + gdb_ip = 28,
> >> + gdb_fpu_ds = 29,
> >> + gdb_dp = 30,
> >> + gdb_fop = 31,
> >> + gdb_xmm0 = 32,
> >> + gdb_xmm1 = 33,
> >> + gdb_xmm2 = 34,
> >> + gdb_xmm3 = 35,
> >> + gdb_xmm4 = 36,
> >> + gdb_xmm5 = 37,
> >> + gdb_xmm6 = 38,
> >> + gdb_xmm7 = 39,
> >> + gdb_mxcsr = 40,
> >> + gdb_mm0 = 41,
> >> + gdb_mm1 = 42,
> >> + gdb_mm2 = 43,
> >> + gdb_mm3 = 44,
> >> + gdb_mm4 = 45,
> >> + gdb_mm5 = 46,
> >> + gdb_mm6 = 47,
> >> + gdb_mm7 = 48
> >> +};
> >> +
> >> +static const
> >> +uint32_t g_gpr_regnums[k_num_gpr_registers] =
> >> +{
> >> + gpr_eax,
> >> + gpr_ebx,
> >> + gpr_ecx,
> >> + gpr_edx,
> >> + gpr_edi,
> >> + gpr_esi,
> >> + gpr_ebp,
> >> + gpr_esp,
> >> + gpr_ss,
> >> + gpr_eflags,
> >> + gpr_orig_ax,
> >> + gpr_eip,
> >> + gpr_cs,
> >> + gpr_ds,
> >> + gpr_es,
> >> + gpr_fs,
> >> + gpr_gs,
> >> +};
> >> +
> >> +static const uint32_t
> >> +g_fpu_regnums[k_num_fpu_registers] =
> >> +{
> >> + fpu_fcw,
> >> + fpu_fsw,
> >> + fpu_ftw,
> >> + fpu_fop,
> >> + fpu_ip,
> >> + fpu_cs,
> >> + fpu_foo,
> >> + fpu_fos,
> >> + fpu_mxcsr,
> >> + fpu_stmm0,
> >> + fpu_stmm1,
> >> + fpu_stmm2,
> >> + fpu_stmm3,
> >> + fpu_stmm4,
> >> + fpu_stmm5,
> >> + fpu_stmm6,
> >> + fpu_stmm7,
> >> + fpu_xmm0,
> >> + fpu_xmm1,
> >> + fpu_xmm2,
> >> + fpu_xmm3,
> >> + fpu_xmm4,
> >> + fpu_xmm5,
> >> + fpu_xmm6,
> >> + fpu_xmm7,
> >> +};
> >> +
> >> +static const RegisterSet
> >> +g_reg_sets[k_num_register_sets] =
> >> +{
> >> + { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums },
> >> + { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums }
> >> +};
> >> +
> >> +// Computes the offset of the given GPR in the user data area.
> >> +#define GPR_OFFSET(regname) \
> >> + (offsetof(RegisterContextLinux_i386::UserArea, regs) + \
> >> + offsetof(RegisterContextLinux_i386::GPR, regname))
> >> +
> >> +// Computes the offset of the given FPR in the user data area.
> >> +#define FPR_OFFSET(regname) \
> >> + (offsetof(RegisterContextLinux_i386::UserArea, i387) + \
> >> + offsetof(RegisterContextLinux_i386::FPU, regname))
> >> +
> >> +// Number of bytes needed to represent a GPR.
> >> +#define GPR_SIZE(reg) sizeof(((RegisterContextLinux_i386::GPR*)NULL)->reg)
> >> +
> >> +// Number of bytes needed to represent a FPR.
> >> +#define FPR_SIZE(reg) sizeof(((RegisterContextLinux_i386::FPU*)NULL)->reg)
> >> +
> >> +// Number of bytes needed to represent the i'th FP register.
> >> +#define FP_SIZE sizeof(((RegisterContextLinux_i386::MMSReg*)NULL)->bytes)
> >> +
> >> +// Number of bytes needed to represent an XMM register.
> >> +#define XMM_SIZE sizeof(RegisterContextLinux_i386::XMMReg)
> >> +
> >> +#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
> >> + { #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, \
> >> + eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg } }
> >> +
> >> +#define DEFINE_FPR(reg, kind1, kind2, kind3, kind4) \
> >> + { #reg, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \
> >> + eFormatHex, { kind1, kind2, kind3, kind4, fpu_##reg } }
> >> +
> >> +#define DEFINE_FP(reg, i) \
> >> + { #reg#i, NULL, FP_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \
> >> + eFormatVectorOfUInt8, \
> >> + { dwarf_##reg##i, dwarf_##reg##i, \
> >> + LLDB_INVALID_REGNUM, gdb_##reg##i, fpu_##reg##i } }
> >> +
> >> +#define DEFINE_XMM(reg, i) \
> >> + { #reg#i, NULL, XMM_SIZE, FPR_OFFSET(reg[i]), eEncodingVector, \
> >> + eFormatVectorOfUInt8, \
> >> + { dwarf_##reg##i, dwarf_##reg##i, \
> >> + LLDB_INVALID_REGNUM, gdb_##reg##i, fpu_##reg##i } }
> >> +
> >> +static RegisterInfo
> >> +g_register_infos[k_num_registers] =
> >> +{
> >> + // General purpose registers.
> >> + DEFINE_GPR(eax, NULL, gcc_eax, dwarf_eax, LLDB_INVALID_REGNUM, gdb_eax),
> >> + DEFINE_GPR(ebx, NULL, gcc_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, gdb_ebx),
> >> + DEFINE_GPR(ecx, NULL, gcc_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, gdb_ecx),
> >> + DEFINE_GPR(edx, NULL, gcc_edx, dwarf_edx, LLDB_INVALID_REGNUM, gdb_edx),
> >> + DEFINE_GPR(edi, NULL, gcc_edi, dwarf_edi, LLDB_INVALID_REGNUM, gdb_edi),
> >> + DEFINE_GPR(esi, NULL, gcc_esi, dwarf_esi, LLDB_INVALID_REGNUM, gdb_esi),
> >> + DEFINE_GPR(ebp, "fp", gcc_ebp, dwarf_ebp, LLDB_INVALID_REGNUM, gdb_ebp),
> >> + DEFINE_GPR(esp, "sp", gcc_esp, dwarf_esp, LLDB_INVALID_REGNUM, gdb_esp),
> >> + DEFINE_GPR(ss, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ss),
> >> + DEFINE_GPR(eflags, "flags", gcc_eflags, dwarf_eflags, LLDB_INVALID_REGNUM, gdb_eflags),
> >> + DEFINE_GPR(eip, "pc", gcc_eip, dwarf_eip, LLDB_INVALID_REGNUM, gdb_eip),
> >> + DEFINE_GPR(cs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_cs),
> >> + DEFINE_GPR(ds, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ds),
> >> + DEFINE_GPR(es, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_es),
> >> + DEFINE_GPR(fs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fs),
> >> + DEFINE_GPR(gs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gs),
> >> +
> >> + // Floating point registers.
> >> + DEFINE_FPR(fcw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fcw),
> >> + DEFINE_FPR(fsw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fsw),
> >> + DEFINE_FPR(ftw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ftw),
> >> + DEFINE_FPR(fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fop),
> >> + DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ip),
> >> + DEFINE_FPR(cs, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_cs),
> >> + DEFINE_FPR(foo, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_dp),
> >> + DEFINE_FPR(fos, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ds),
> >> + DEFINE_FPR(mxcsr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_mxcsr),
> >> +
> >> + DEFINE_FP(stmm, 0),
> >> + DEFINE_FP(stmm, 1),
> >> + DEFINE_FP(stmm, 2),
> >> + DEFINE_FP(stmm, 3),
> >> + DEFINE_FP(stmm, 4),
> >> + DEFINE_FP(stmm, 5),
> >> + DEFINE_FP(stmm, 6),
> >> + DEFINE_FP(stmm, 7),
> >> +
> >> + // XMM registers
> >> + DEFINE_XMM(xmm, 0),
> >> + DEFINE_XMM(xmm, 1),
> >> + DEFINE_XMM(xmm, 2),
> >> + DEFINE_XMM(xmm, 3),
> >> + DEFINE_XMM(xmm, 4),
> >> + DEFINE_XMM(xmm, 5),
> >> + DEFINE_XMM(xmm, 6),
> >> + DEFINE_XMM(xmm, 7),
> >> +
> >> +};
> >> +
> >> +static unsigned GetRegOffset(unsigned reg)
> >> +{
> >> + assert(reg < k_num_registers && "Invalid register number.");
> >> + return g_register_infos[reg].byte_offset;
> >> +}
> >> +
> >> +static unsigned GetRegSize(unsigned reg)
> >> +{
> >> + assert(reg < k_num_registers && "Invalid register number.");
> >> + return g_register_infos[reg].byte_size;
> >> +}
> >> +
> >> +static bool IsGPR(unsigned reg)
> >> +{
> >> + return reg <= k_last_gpr; // GPR's come first.
> >> +}
> >> +
> >> +static bool IsFPR(unsigned reg)
> >> +{
> >> + return (k_first_fpr <= reg && reg <= k_last_fpr);
> >> +}
> >> +
> >> +
> >> +RegisterContextLinux_i386::RegisterContextLinux_i386(Thread &thread,
> >> + uint32_t concrete_frame_idx)
> >> + : RegisterContextLinux(thread, concrete_frame_idx)
> >> +{
> >> +}
> >> +
> >> +RegisterContextLinux_i386::~RegisterContextLinux_i386()
> >> +{
> >> +}
> >> +
> >> +ProcessMonitor &
> >> +RegisterContextLinux_i386::GetMonitor()
> >> +{
> >> + ProcessLinux *process = static_cast<ProcessLinux*>(CalculateProcess());
> >> + return process->GetMonitor();
> >> +}
> >> +
> >> +void
> >> +RegisterContextLinux_i386::Invalidate()
> >> +{
> >> +}
> >> +
> >> +void
> >> +RegisterContextLinux_i386::InvalidateAllRegisters()
> >> +{
> >> +}
> >> +
> >> +size_t
> >> +RegisterContextLinux_i386::GetRegisterCount()
> >> +{
> >> + return k_num_registers;
> >> +}
> >> +
> >> +const RegisterInfo *
> >> +RegisterContextLinux_i386::GetRegisterInfoAtIndex(uint32_t reg)
> >> +{
> >> + if (reg < k_num_registers)
> >> + return &g_register_infos[reg];
> >> + else
> >> + return NULL;
> >> +}
> >> +
> >> +size_t
> >> +RegisterContextLinux_i386::GetRegisterSetCount()
> >> +{
> >> + return k_num_register_sets;
> >> +}
> >> +
> >> +const RegisterSet *
> >> +RegisterContextLinux_i386::GetRegisterSet(uint32_t set)
> >> +{
> >> + if (set < k_num_register_sets)
> >> + return &g_reg_sets[set];
> >> + else
> >> + return NULL;
> >> +}
> >> +
> >> +bool
> >> +RegisterContextLinux_i386::ReadRegisterValue(uint32_t reg,
> >> + Scalar &value)
> >> +{
> >> + ProcessMonitor &monitor = GetMonitor();
> >> + return monitor.ReadRegisterValue(GetRegOffset(reg), value);
> >> +}
> >> +
> >> +bool
> >> +RegisterContextLinux_i386::ReadRegisterBytes(uint32_t reg,
> >> + DataExtractor &data)
> >> +{
> >> + uint8_t *buf = reinterpret_cast<uint8_t*>(&user);
> >> + bool status;
> >> +
> >> + if (IsGPR(reg))
> >> + status = ReadGPR();
> >> + else if (IsFPR(reg))
> >> + status = ReadFPR();
> >> + else
> >> + {
> >> + assert(false && "invalid register number");
> >> + status = false;
> >> + }
> >> +
> >> + if (status)
> >> + data.SetData(buf + GetRegOffset(reg), GetRegSize(reg), lldb::endian::InlHostByteOrder());
> >> +
> >> + return status;
> >> +}
> >> +
> >> +bool
> >> +RegisterContextLinux_i386::ReadAllRegisterValues(DataBufferSP &data_sp)
> >> +{
> >> + return false;
> >> +}
> >> +
> >> +bool
> >> +RegisterContextLinux_i386::WriteRegisterValue(uint32_t reg,
> >> + const Scalar &value)
> >> +{
> >> + ProcessMonitor &monitor = GetMonitor();
> >> + return monitor.WriteRegisterValue(GetRegOffset(reg), value);
> >> +}
> >> +
> >> +bool
> >> +RegisterContextLinux_i386::WriteRegisterBytes(uint32_t reg,
> >> + DataExtractor &data,
> >> + uint32_t data_offset)
> >> +{
> >> + return false;
> >> +}
> >> +
> >> +bool
> >> +RegisterContextLinux_i386::WriteAllRegisterValues(const DataBufferSP &data)
> >> +{
> >> + return false;
> >> +}
> >> +
> >> +bool
> >> +RegisterContextLinux_i386::UpdateAfterBreakpoint()
> >> +{
> >> + // PC points one byte past the int3 responsible for the breakpoint.
> >> + lldb::addr_t pc;
> >> +
> >> + if ((pc = GetPC()) == LLDB_INVALID_ADDRESS)
> >> + return false;
> >> +
> >> + SetPC(pc - 1);
> >> + return true;
> >> +}
> >> +
> >> +uint32_t
> >> +RegisterContextLinux_i386::ConvertRegisterKindToRegisterNumber(uint32_t kind,
> >> + uint32_t num)
> >> +{
> >> + if (kind == eRegisterKindGeneric)
> >> + {
> >> + switch (num)
> >> + {
> >> + case LLDB_REGNUM_GENERIC_PC: return gpr_eip;
> >> + case LLDB_REGNUM_GENERIC_SP: return gpr_esp;
> >> + case LLDB_REGNUM_GENERIC_FP: return gpr_ebp;
> >> + case LLDB_REGNUM_GENERIC_FLAGS: return gpr_eflags;
> >> + case LLDB_REGNUM_GENERIC_RA:
> >> + default:
> >> + return LLDB_INVALID_REGNUM;
> >> + }
> >> + }
> >> +
> >> + if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF)
> >> + {
> >> + switch (num)
> >> + {
> >> + case dwarf_eax: return gpr_eax;
> >> + case dwarf_edx: return gpr_edx;
> >> + case dwarf_ecx: return gpr_ecx;
> >> + case dwarf_ebx: return gpr_ebx;
> >> + case dwarf_esi: return gpr_esi;
> >> + case dwarf_edi: return gpr_edi;
> >> + case dwarf_ebp: return gpr_ebp;
> >> + case dwarf_esp: return gpr_esp;
> >> + case dwarf_eip: return gpr_eip;
> >> + case dwarf_xmm0: return fpu_xmm0;
> >> + case dwarf_xmm1: return fpu_xmm1;
> >> + case dwarf_xmm2: return fpu_xmm2;
> >> + case dwarf_xmm3: return fpu_xmm3;
> >> + case dwarf_xmm4: return fpu_xmm4;
> >> + case dwarf_xmm5: return fpu_xmm5;
> >> + case dwarf_xmm6: return fpu_xmm6;
> >> + case dwarf_xmm7: return fpu_xmm7;
> >> + case dwarf_stmm0: return fpu_stmm0;
> >> + case dwarf_stmm1: return fpu_stmm1;
> >> + case dwarf_stmm2: return fpu_stmm2;
> >> + case dwarf_stmm3: return fpu_stmm3;
> >> + case dwarf_stmm4: return fpu_stmm4;
> >> + case dwarf_stmm5: return fpu_stmm5;
> >> + case dwarf_stmm6: return fpu_stmm6;
> >> + case dwarf_stmm7: return fpu_stmm7;
> >> + default:
> >> + return LLDB_INVALID_REGNUM;
> >> + }
> >> + }
> >> +
> >> + if (kind == eRegisterKindGDB)
> >> + {
> >> + switch (num)
> >> + {
> >> + case gdb_eax : return gpr_eax;
> >> + case gdb_ebx : return gpr_ebx;
> >> + case gdb_ecx : return gpr_ecx;
> >> + case gdb_edx : return gpr_edx;
> >> + case gdb_esi : return gpr_esi;
> >> + case gdb_edi : return gpr_edi;
> >> + case gdb_ebp : return gpr_ebp;
> >> + case gdb_esp : return gpr_esp;
> >> + case gdb_eip : return gpr_eip;
> >> + case gdb_eflags : return gpr_eflags;
> >> + case gdb_cs : return gpr_cs;
> >> + case gdb_ss : return gpr_ss;
> >> + case gdb_ds : return gpr_ds;
> >> + case gdb_es : return gpr_es;
> >> + case gdb_fs : return gpr_fs;
> >> + case gdb_gs : return gpr_gs;
> >> + case gdb_stmm0 : return fpu_stmm0;
> >> + case gdb_stmm1 : return fpu_stmm1;
> >> + case gdb_stmm2 : return fpu_stmm2;
> >> + case gdb_stmm3 : return fpu_stmm3;
> >> + case gdb_stmm4 : return fpu_stmm4;
> >> + case gdb_stmm5 : return fpu_stmm5;
> >> + case gdb_stmm6 : return fpu_stmm6;
> >> + case gdb_stmm7 : return fpu_stmm7;
> >> + case gdb_fcw : return fpu_fcw;
> >> + case gdb_fsw : return fpu_fsw;
> >> + case gdb_ftw : return fpu_ftw;
> >> + case gdb_fpu_cs : return fpu_cs;
> >> + case gdb_ip : return fpu_ip;
> >> + case gdb_fpu_ds : return fpu_fos;
> >> + case gdb_dp : return fpu_foo;
> >> + case gdb_fop : return fpu_fop;
> >> + case gdb_xmm0 : return fpu_xmm0;
> >> + case gdb_xmm1 : return fpu_xmm1;
> >> + case gdb_xmm2 : return fpu_xmm2;
> >> + case gdb_xmm3 : return fpu_xmm3;
> >> + case gdb_xmm4 : return fpu_xmm4;
> >> + case gdb_xmm5 : return fpu_xmm5;
> >> + case gdb_xmm6 : return fpu_xmm6;
> >> + case gdb_xmm7 : return fpu_xmm7;
> >> + case gdb_mxcsr : return fpu_mxcsr;
> >> + default:
> >> + return LLDB_INVALID_REGNUM;
> >> + }
> >> + }
> >> + else if (kind == eRegisterKindLLDB)
> >> + {
> >> + return num;
> >> + }
> >> +
> >> + return LLDB_INVALID_REGNUM;
> >> +}
> >> +
> >> +bool
> >> +RegisterContextLinux_i386::HardwareSingleStep(bool enable)
> >> +{
> >> + enum { TRACE_BIT = 0x100 };
> >> + uint64_t eflags;
> >> +
> >> + if ((eflags = ReadRegisterAsUnsigned(gpr_eflags, -1UL)) == -1UL)
> >> + return false;
> >> +
> >> + if (enable)
> >> + {
> >> + if (eflags & TRACE_BIT)
> >> + return true;
> >> +
> >> + eflags |= TRACE_BIT;
> >> + }
> >> + else
> >> + {
> >> + if (!(eflags & TRACE_BIT))
> >> + return false;
> >> +
> >> + eflags &= ~TRACE_BIT;
> >> + }
> >> +
> >> + return WriteRegisterFromUnsigned(gpr_eflags, eflags);
> >> +}
> >> +
> >> +bool
> >> +RegisterContextLinux_i386::ReadGPR()
> >> +{
> >> + ProcessMonitor &monitor = GetMonitor();
> >> + return monitor.ReadGPR(&user.regs);
> >> +}
> >> +
> >> +bool
> >> +RegisterContextLinux_i386::ReadFPR()
> >> +{
> >> + ProcessMonitor &monitor = GetMonitor();
> >> + return monitor.ReadFPR(&user.i387);
> >> +}
> >> diff --git a/source/Plugins/Process/Linux/RegisterContextLinux_i386.h b/source/Plugins/Process/Linux/RegisterContextLinux_i386.h
> >> new file mode 100644
> >> index 0000000..30b3d70
> >> --- /dev/null
> >> +++ b/source/Plugins/Process/Linux/RegisterContextLinux_i386.h
> >> @@ -0,0 +1,148 @@
> >> +//===-- RegisterContextLinux_i386.h ------------------------------*- C++ -*-===//
> >> +//
> >> +// The LLVM Compiler Infrastructure
> >> +//
> >> +// This file is distributed under the University of Illinois Open Source
> >> +// License. See LICENSE.TXT for details.
> >> +//
> >> +//===----------------------------------------------------------------------===//
> >> +
> >> +#ifndef liblldb_RegisterContextLinux_i386_h_
> >> +#define liblldb_RegisterContextLinux_i386_h_
> >> +
> >> +// C Includes
> >> +// C++ Includes
> >> +// Other libraries and framework includes
> >> +// Project includes
> >> +#include "RegisterContextLinux.h"
> >> +
> >> +class RegisterContextLinux_i386 : public RegisterContextLinux
> >> +{
> >> +public:
> >> + RegisterContextLinux_i386(lldb_private::Thread &thread,
> >> + uint32_t concreate_frame_idx);
> >> +
> >> + ~RegisterContextLinux_i386();
> >> +
> >> + void
> >> + Invalidate();
> >> +
> >> + void
> >> + InvalidateAllRegisters();
> >> +
> >> + size_t
> >> + GetRegisterCount();
> >> +
> >> + const lldb::RegisterInfo *
> >> + GetRegisterInfoAtIndex(uint32_t reg);
> >> +
> >> + size_t
> >> + GetRegisterSetCount();
> >> +
> >> + const lldb::RegisterSet *
> >> + GetRegisterSet(uint32_t set);
> >> +
> >> + bool
> >> + ReadRegisterValue(uint32_t reg, lldb_private::Scalar &value);
> >> +
> >> + bool
> >> + ReadRegisterBytes(uint32_t reg, lldb_private::DataExtractor &data);
> >> +
> >> + bool
> >> + ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
> >> +
> >> + bool
> >> + WriteRegisterValue(uint32_t reg, const lldb_private::Scalar &value);
> >> +
> >> + bool
> >> + WriteRegisterBytes(uint32_t reg, lldb_private::DataExtractor &data,
> >> + uint32_t data_offset = 0);
> >> +
> >> + bool
> >> + WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
> >> +
> >> + uint32_t
> >> + ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num);
> >> +
> >> + bool
> >> + HardwareSingleStep(bool enable);
> >> +
> >> + bool
> >> + UpdateAfterBreakpoint();
> >> +
> >> + struct GPR
> >> + {
> >> + uint32_t ebx;
> >> + uint32_t ecx;
> >> + uint32_t edx;
> >> + uint32_t esi;
> >> + uint32_t edi;
> >> + uint32_t ebp;
> >> + uint32_t eax;
> >> + uint32_t ds;
> >> + uint32_t es;
> >> + uint32_t fs;
> >> + uint32_t gs;
> >> + uint32_t orig_ax;
> >> + uint32_t eip;
> >> + uint32_t cs;
> >> + uint32_t eflags;
> >> + uint32_t esp;
> >> + uint32_t ss;
> >> + };
> >> +
> >> + struct MMSReg
> >> + {
> >> + uint8_t bytes[8];
> >> + };
> >> +
> >> + struct XMMReg
> >> + {
> >> + uint8_t bytes[16];
> >> + };
> >> +
> >> + struct FPU
> >> + {
> >> + uint16_t fcw;
> >> + uint16_t fsw;
> >> + uint16_t ftw;
> >> + uint16_t fop;
> >> + uint32_t ip;
> >> + uint32_t cs;
> >> + uint32_t foo;
> >> + uint32_t fos;
> >> + uint32_t mxcsr;
> >> + uint32_t reserved;
> >> + MMSReg stmm[8];
> >> + XMMReg xmm[8];
> >> + uint32_t pad[56];
> >> + };
> >> +
> >> + struct UserArea
> >> + {
> >> + GPR regs; // General purpose registers.
> >> + int32_t fpvalid; // True if FPU is being used.
> >> + FPU i387; // FPU registers.
> >> + uint32_t tsize; // Text segment size.
> >> + uint32_t dsize; // Data segment size.
> >> + uint32_t ssize; // Stack segment size.
> >> + uint32_t start_code; // VM address of text.
> >> + uint32_t start_stack; // VM address of stack bottom (top in rsp).
> >> + int32_t signal; // Signal causing core dump.
> >> + int32_t reserved; // Unused.
> >> + uint32_t ar0; // Location of GPR's.
> >> + FPU* fpstate; // Location of FPR's.
> >> + uint32_t magic; // Identifier for core dumps.
> >> + char u_comm[32]; // Command causing core dump.
> >> + uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7).
> >> + };
> >> +private:
> >> + UserArea user;
> >> +
> >> + ProcessMonitor &GetMonitor();
> >> +
> >> + bool ReadGPR();
> >> + bool ReadFPR();
> >> +};
> >> +
> >> +#endif // #ifndef liblldb_RegisterContextLinux_i386_h_
> >
> >
> > --
> > steve
> >
>
--
steve
More information about the lldb-commits
mailing list