[Lldb-commits] x86_32 linux support

Greg Clayton gclayton at apple.com
Mon Feb 28 11:30:48 PST 2011


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?

> 
>> 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
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20110228/5f9cd8fd/attachment.html>


More information about the lldb-commits mailing list