[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