diff options
author | Ashok Thirumurthi <ashok.thirumurthi@intel.com> | 2013-05-01 20:17:59 +0000 |
---|---|---|
committer | Ashok Thirumurthi <ashok.thirumurthi@intel.com> | 2013-05-01 20:17:59 +0000 |
commit | e4a862f79428f7b6bb29de6b7133e111f1cd2a11 (patch) | |
tree | 6b6196d0729cd8aec6242d7dfbf94932ed50e8eb | |
parent | bc668b06428765e38006f3822bd0eae424f492b0 (diff) | |
download | bcm5719-llvm-e4a862f79428f7b6bb29de6b7133e111f1cd2a11.tar.gz bcm5719-llvm-e4a862f79428f7b6bb29de6b7133e111f1cd2a11.zip |
Platform-specific specialization for the GPR register file.
- Required for platform-independant handling of general purpose registers (i.e. for core dumps).
Thanks to Samuel Jacob for this patch.
llvm-svn: 180878
9 files changed, 507 insertions, 242 deletions
diff --git a/lldb/source/Plugins/Process/FreeBSD/RegisterContextFreeBSD_x86_64.h b/lldb/source/Plugins/Process/FreeBSD/RegisterContextFreeBSD_x86_64.h index 25590e74c09..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/FreeBSD/RegisterContextFreeBSD_x86_64.h +++ b/lldb/source/Plugins/Process/FreeBSD/RegisterContextFreeBSD_x86_64.h @@ -1,43 +0,0 @@ -//===-- RegisterContextFreeBSD_x86_64.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_RegisterContextFreeBSD_x86_64_H_ -#define liblldb_RegisterContextFreeBSD_x86_64_H_ - - typedef struct _GPR - { - uint64_t r15; - uint64_t r14; - uint64_t r13; - uint64_t r12; - uint64_t r11; - uint64_t r10; - uint64_t r9; - uint64_t r8; - uint64_t rdi; - uint64_t rsi; - uint64_t rbp; - uint64_t rbx; - uint64_t rdx; - uint64_t rcx; - uint64_t rax; - uint32_t trapno; - uint16_t fs; - uint16_t gs; - uint32_t err; - uint16_t es; - uint16_t ds; - uint64_t rip; - uint64_t cs; - uint64_t rflags; - uint64_t rsp; - uint64_t ss; - } GPR; - -#endif diff --git a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h index d392581c286..e69de29bb2d 100644 --- a/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h +++ b/lldb/source/Plugins/Process/Linux/RegisterContextLinux_x86_64.h @@ -1,48 +0,0 @@ -//===-- RegisterContextLinux_x86_64.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_x86_64_H_ -#define liblldb_RegisterContextLinux_x86_64_H_ - -// Architecture specific register sets are described by the ELF core file format -// for use with core dumps and PTRACE extensions like PTRACE_GETREGSET -#include <linux/elf.h> - -typedef struct _GPR -{ - uint64_t r15; - uint64_t r14; - uint64_t r13; - uint64_t r12; - uint64_t rbp; - uint64_t rbx; - uint64_t r11; - uint64_t r10; - uint64_t r9; - uint64_t r8; - uint64_t rax; - uint64_t rcx; - uint64_t rdx; - uint64_t rsi; - uint64_t rdi; - uint64_t orig_ax; - uint64_t rip; - uint64_t cs; - uint64_t rflags; - uint64_t rsp; - uint64_t ss; - uint64_t fs_base; - uint64_t gs_base; - uint64_t ds; - uint64_t es; - uint64_t fs; - uint64_t gs; -} GPR; - -#endif diff --git a/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp b/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp index 94ee8cbdc2c..3b2ae03bd71 100644 --- a/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp +++ b/lldb/source/Plugins/Process/POSIX/POSIXThread.cpp @@ -28,6 +28,8 @@ #include "RegisterContext_i386.h" #include "RegisterContext_x86_64.h" #include "RegisterContextPOSIX.h" +#include "RegisterContextLinux_x86_64.h" +#include "RegisterContextFreeBSD_x86_64.h" #include "UnwindLLDB.h" @@ -97,7 +99,12 @@ POSIXThread::GetRegisterContext() break; case ArchSpec::eCore_x86_64_x86_64: - m_reg_context_sp.reset(new RegisterContext_x86_64(*this, 0)); +#ifdef __linux__ + m_reg_context_sp.reset(new RegisterContextLinux_x86_64(*this, 0)); +#endif +#ifdef __FreeBSD__ + m_reg_context_sp.reset(new RegisterContextFreeBSD_x86_64(*this, 0)); +#endif break; } } diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.cpp b/lldb/source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.cpp new file mode 100644 index 00000000000..fffd2e639e4 --- /dev/null +++ b/lldb/source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.cpp @@ -0,0 +1,134 @@ +//===-- RegisterContextFreeBSD_x86_64.h ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// + +#include "RegisterContextFreeBSD_x86_64.h" + +// Computes the offset of the given GPR in the user data area. +#define GPR_OFFSET(regname) \ + (offsetof(RegisterContext_x86_64::UserArea, regs) + \ + offsetof(GPR, regname)) + +// Updates the FreeBSD specific information (offset and size) +#define UPDATE_GPR_INFO(reg) \ +do { \ + m_register_infos[gpr_##reg].byte_size = sizeof(GPR::reg); \ + m_register_infos[gpr_##reg].byte_offset = GPR_OFFSET(reg); \ +} while(false); + +#define UPDATE_I386_GPR_INFO(i386_reg, reg) \ +do { \ + m_register_infos[gpr_##i386_reg].byte_offset = GPR_OFFSET(reg); \ +} while(false); + +typedef struct _GPR +{ + uint64_t r15; + uint64_t r14; + uint64_t r13; + uint64_t r12; + uint64_t r11; + uint64_t r10; + uint64_t r9; + uint64_t r8; + uint64_t rdi; + uint64_t rsi; + uint64_t rbp; + uint64_t rbx; + uint64_t rdx; + uint64_t rcx; + uint64_t rax; + uint32_t trapno; + uint16_t fs; + uint16_t gs; + uint32_t err; + uint16_t es; + uint16_t ds; + uint64_t rip; + uint64_t cs; + uint64_t rflags; + uint64_t rsp; + uint64_t ss; +} GPR; + +RegisterInfo *RegisterContextFreeBSD_x86_64::m_register_infos = nullptr; + +RegisterContextFreeBSD_x86_64::RegisterContextFreeBSD_x86_64(Thread &thread, uint32_t concrete_frame_idx): + RegisterContext_x86_64(thread, concrete_frame_idx) +{ +} + +RegisterContextFreeBSD_x86_64::~RegisterContextFreeBSD_x86_64() +{ + if (m_register_infos) + delete m_register_infos; + m_register_infos = nullptr; +} + +size_t +RegisterContextFreeBSD_x86_64::GetGPRSize() +{ + return sizeof(GPR); +} + +const RegisterInfo * +RegisterContextFreeBSD_x86_64::GetRegisterInfo() +{ + // Allocate RegisterInfo only once + if (m_register_infos == nullptr) + { + m_register_infos = new RegisterInfo[k_num_registers]; + // Copy the register information from base class + memcpy(m_register_infos, RegisterContext_x86_64::GetRegisterInfo(), + sizeof(RegisterInfo) * k_num_registers); + // Update the FreeBSD specfic register information(offset and size) + UpdateRegisterInfo(); + } + return m_register_infos; +} + +void +RegisterContextFreeBSD_x86_64::UpdateRegisterInfo() +{ + UPDATE_GPR_INFO(rax); + UPDATE_GPR_INFO(rbx); + UPDATE_GPR_INFO(rcx); + UPDATE_GPR_INFO(rdx); + UPDATE_GPR_INFO(rdi); + UPDATE_GPR_INFO(rsi); + UPDATE_GPR_INFO(rbp); + UPDATE_GPR_INFO(rsp); + UPDATE_GPR_INFO(r8); + UPDATE_GPR_INFO(r9); + UPDATE_GPR_INFO(r10); + UPDATE_GPR_INFO(r11); + UPDATE_GPR_INFO(r12); + UPDATE_GPR_INFO(r13); + UPDATE_GPR_INFO(r14); + UPDATE_GPR_INFO(r15); + UPDATE_GPR_INFO(rip); + UPDATE_GPR_INFO(rflags); + UPDATE_GPR_INFO(cs); + UPDATE_GPR_INFO(fs); + UPDATE_GPR_INFO(gs); + UPDATE_GPR_INFO(ss); + UPDATE_GPR_INFO(ds); + UPDATE_GPR_INFO(es); + + UPDATE_I386_GPR_INFO(eax, rax); + UPDATE_I386_GPR_INFO(ebx, rbx); + UPDATE_I386_GPR_INFO(ecx, rcx); + UPDATE_I386_GPR_INFO(edx, rdx); + UPDATE_I386_GPR_INFO(edi, rdi); + UPDATE_I386_GPR_INFO(esi, rsi); + UPDATE_I386_GPR_INFO(ebp, rbp); + UPDATE_I386_GPR_INFO(esp, rsp); + UPDATE_I386_GPR_INFO(eip, rip); + UPDATE_I386_GPR_INFO(eflags, rflags); +} + diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.h b/lldb/source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.h new file mode 100644 index 00000000000..355baafb7e4 --- /dev/null +++ b/lldb/source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.h @@ -0,0 +1,35 @@ +//===-- RegisterContextFreeBSD_x86_64.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_RegisterContextFreeBSD_x86_64_H_ +#define liblldb_RegisterContextFreeBSD_x86_64_H_ + +#include "Plugins/Process/POSIX/RegisterContext_x86_64.h" + +using namespace lldb_private; + +class RegisterContextFreeBSD_x86_64: + public RegisterContext_x86_64 +{ +public: + RegisterContextFreeBSD_x86_64(Thread &thread, uint32_t concrete_frame_idx); + virtual ~RegisterContextFreeBSD_x86_64(); + + size_t GetGPRSize(); + +protected: + virtual const lldb_private::RegisterInfo * + GetRegisterInfo(); + +private: + static lldb_private::RegisterInfo *m_register_infos; + void UpdateRegisterInfo(); +}; + +#endif diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.cpp b/lldb/source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.cpp new file mode 100644 index 00000000000..3d385df41da --- /dev/null +++ b/lldb/source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.cpp @@ -0,0 +1,135 @@ +//===-- RegisterContextLinux_x86_64.h --------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// + +#include "RegisterContextLinux_x86_64.h" + +// Computes the offset of the given GPR in the user data area. +#define GPR_OFFSET(regname) \ + (offsetof(RegisterContext_x86_64::UserArea, regs) + \ + offsetof(GPR, regname)) + +// Updates the Linux specific information (offset and size) +#define UPDATE_GPR_INFO(reg) \ +do { \ + m_register_infos[gpr_##reg].byte_size = sizeof(GPR::reg); \ + m_register_infos[gpr_##reg].byte_offset = GPR_OFFSET(reg); \ +} while(false); + +#define UPDATE_I386_GPR_INFO(i386_reg, reg) \ +do { \ + m_register_infos[gpr_##i386_reg].byte_offset = GPR_OFFSET(reg); \ +} while(false); + +typedef struct _GPR +{ + uint64_t r15; + uint64_t r14; + uint64_t r13; + uint64_t r12; + uint64_t rbp; + uint64_t rbx; + uint64_t r11; + uint64_t r10; + uint64_t r9; + uint64_t r8; + uint64_t rax; + uint64_t rcx; + uint64_t rdx; + uint64_t rsi; + uint64_t rdi; + uint64_t orig_ax; + uint64_t rip; + uint64_t cs; + uint64_t rflags; + uint64_t rsp; + uint64_t ss; + uint64_t fs_base; + uint64_t gs_base; + uint64_t ds; + uint64_t es; + uint64_t fs; + uint64_t gs; +} GPR; + +RegisterInfo *RegisterContextLinux_x86_64::m_register_infos = nullptr; + +RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(Thread &thread, uint32_t concrete_frame_idx): + RegisterContext_x86_64(thread, concrete_frame_idx) +{ +} + +RegisterContextLinux_x86_64::~RegisterContextLinux_x86_64() +{ + if (m_register_infos) + delete m_register_infos; + m_register_infos = nullptr; +} + +size_t +RegisterContextLinux_x86_64::GetGPRSize() +{ + return sizeof(GPR); +} + +const RegisterInfo * +RegisterContextLinux_x86_64::GetRegisterInfo() +{ + // Allocate RegisterInfo only once + if (m_register_infos == nullptr) + { + m_register_infos = new RegisterInfo[k_num_registers]; + // Copy the register information from base class + memcpy(m_register_infos, RegisterContext_x86_64::GetRegisterInfo(), + sizeof(RegisterInfo) * k_num_registers); + // Update the Linux specific register information(offset and size) + UpdateRegisterInfo(); + } + return m_register_infos; +} + +void +RegisterContextLinux_x86_64::UpdateRegisterInfo() +{ + UPDATE_GPR_INFO(rax); + UPDATE_GPR_INFO(rbx); + UPDATE_GPR_INFO(rcx); + UPDATE_GPR_INFO(rdx); + UPDATE_GPR_INFO(rdi); + UPDATE_GPR_INFO(rsi); + UPDATE_GPR_INFO(rbp); + UPDATE_GPR_INFO(rsp); + UPDATE_GPR_INFO(r8); + UPDATE_GPR_INFO(r9); + UPDATE_GPR_INFO(r10); + UPDATE_GPR_INFO(r11); + UPDATE_GPR_INFO(r12); + UPDATE_GPR_INFO(r13); + UPDATE_GPR_INFO(r14); + UPDATE_GPR_INFO(r15); + UPDATE_GPR_INFO(rip); + UPDATE_GPR_INFO(rflags); + UPDATE_GPR_INFO(cs); + UPDATE_GPR_INFO(fs); + UPDATE_GPR_INFO(gs); + UPDATE_GPR_INFO(ss); + UPDATE_GPR_INFO(ds); + UPDATE_GPR_INFO(es); + + UPDATE_I386_GPR_INFO(eax, rax); + UPDATE_I386_GPR_INFO(ebx, rbx); + UPDATE_I386_GPR_INFO(ecx, rcx); + UPDATE_I386_GPR_INFO(edx, rdx); + UPDATE_I386_GPR_INFO(edi, rdi); + UPDATE_I386_GPR_INFO(esi, rsi); + UPDATE_I386_GPR_INFO(ebp, rbp); + UPDATE_I386_GPR_INFO(esp, rsp); + UPDATE_I386_GPR_INFO(eip, rip); + UPDATE_I386_GPR_INFO(eflags, rflags); +} + diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.h b/lldb/source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.h new file mode 100644 index 00000000000..1df607f63c8 --- /dev/null +++ b/lldb/source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.h @@ -0,0 +1,35 @@ +//===-- RegisterContextLinux_x86_64.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_x86_64_H_ +#define liblldb_RegisterContextLinux_x86_64_H_ + +#include "Plugins/Process/POSIX/RegisterContext_x86_64.h" + +using namespace lldb_private; + +class RegisterContextLinux_x86_64: + public RegisterContext_x86_64 +{ +public: + RegisterContextLinux_x86_64(Thread &thread, uint32_t concrete_frame_idx); + virtual ~RegisterContextLinux_x86_64(); + + size_t GetGPRSize(); + +protected: + virtual const lldb_private::RegisterInfo * + GetRegisterInfo(); + +private: + static lldb_private::RegisterInfo *m_register_infos; + void UpdateRegisterInfo(); +}; + +#endif diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp b/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp index c99e93455cd..2a0c68e1430 100644 --- a/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp +++ b/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp @@ -33,107 +33,6 @@ using namespace lldb; #define NT_X86_XSTATE 0x202 #endif -// Internal codes for all x86_64 registers. -enum -{ - k_first_gpr, - gpr_rax = k_first_gpr, - gpr_rbx, - gpr_rcx, - gpr_rdx, - gpr_rdi, - gpr_rsi, - gpr_rbp, - gpr_rsp, - gpr_r8, - gpr_r9, - gpr_r10, - gpr_r11, - gpr_r12, - gpr_r13, - gpr_r14, - gpr_r15, - gpr_rip, - gpr_rflags, - gpr_cs, - gpr_fs, - gpr_gs, - gpr_ss, - gpr_ds, - gpr_es, - gpr_eax, - gpr_ebx, - gpr_ecx, - gpr_edx, - gpr_edi, - gpr_esi, - gpr_ebp, - gpr_esp, - gpr_eip, - gpr_eflags, - k_last_gpr = gpr_eflags, // eRegisterKindLLDB == 33 - - k_first_fpr, - fpu_fcw = k_first_fpr, - fpu_fsw, - fpu_ftw, - fpu_fop, - fpu_ip, - fpu_cs, - fpu_dp, - fpu_ds, - fpu_mxcsr, - fpu_mxcsrmask, - 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, - fpu_xmm8, - fpu_xmm9, - fpu_xmm10, - fpu_xmm11, - fpu_xmm12, - fpu_xmm13, - fpu_xmm14, - fpu_xmm15, - k_last_fpr = fpu_xmm15, - k_first_avx, - fpu_ymm0 = k_first_avx, - fpu_ymm1, - fpu_ymm2, - fpu_ymm3, - fpu_ymm4, - fpu_ymm5, - fpu_ymm6, - fpu_ymm7, - fpu_ymm8, - fpu_ymm9, - fpu_ymm10, - fpu_ymm11, - fpu_ymm12, - fpu_ymm13, - fpu_ymm14, - fpu_ymm15, - k_last_avx = fpu_ymm15, - - k_num_registers, - k_num_gpr_registers = k_last_gpr - k_first_gpr + 1, - k_num_fpr_registers = k_last_fpr - k_first_fpr + 1, - k_num_avx_registers = k_last_avx - k_first_avx + 1 -}; - enum { gcc_dwarf_gpr_rax = 0, @@ -386,11 +285,6 @@ g_reg_sets[k_num_register_sets] = { "Advanced Vector Extensions", "avx", k_num_avx_registers, g_avx_regnums } }; -// Computes the offset of the given GPR in the user data area. -#define GPR_OFFSET(regname) \ - (offsetof(RegisterContext_x86_64::UserArea, regs) + \ - offsetof(GPR, regname)) - // Computes the offset of the given FPR in the user data area. #define FPR_OFFSET(regname) \ (offsetof(RegisterContext_x86_64::UserArea, i387) + \ @@ -403,9 +297,6 @@ g_reg_sets[k_num_register_sets] = offsetof(RegisterContext_x86_64::FPR, ymm_set) + \ offsetof(RegisterContext_x86_64::YMM, regname)) -// Number of bytes needed to represent a GPR. -#define GPR_SIZE(reg) sizeof(((GPR*)NULL)->reg) - // Number of bytes needed to represent a i386 GPR #define GPR_i386_SIZE(reg) sizeof(((RegisterContext_i386::GPR*)NULL)->reg) @@ -421,16 +312,17 @@ g_reg_sets[k_num_register_sets] = // Number of bytes needed to represent a YMM register. #define YMM_SIZE sizeof(RegisterContext_x86_64::YMMReg) -#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ - { #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, \ +// Note that the size and offset will be updated by platform-specific classes. +#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ + { #reg, alt, 0, 0, eEncodingUint, \ eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg }, NULL, NULL } #define DEFINE_GPR_i386(reg_i386, reg_x86_64, alt, kind1, kind2, kind3, kind4) \ - { #reg_i386, alt, GPR_i386_SIZE(reg_i386), GPR_OFFSET(reg_x86_64), eEncodingUint, \ + { #reg_i386, alt, GPR_i386_SIZE(reg_i386), 0, eEncodingUint, \ eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg_i386 }, NULL, NULL } -#define DEFINE_FPR(reg, kind1, kind2, kind3, kind4) \ - { #reg, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \ +#define DEFINE_FPR(reg, kind1, kind2, kind3, kind4) \ + { #reg, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \ eFormatHex, { kind1, kind2, kind3, kind4, fpu_##reg }, NULL, NULL } #define DEFINE_FP(reg, i) \ @@ -445,13 +337,13 @@ g_reg_sets[k_num_register_sets] = { gcc_dwarf_fpu_##reg##i, gcc_dwarf_fpu_##reg##i, \ LLDB_INVALID_REGNUM, gdb_fpu_##reg##i, fpu_##reg##i }, NULL, NULL } -#define DEFINE_YMM(reg, i) \ +#define DEFINE_YMM(reg, i) \ { #reg#i, NULL, YMM_SIZE, YMM_OFFSET(reg[i]), eEncodingVector, \ - eFormatVectorOfUInt8, \ - { gcc_dwarf_fpu_##reg##i, gcc_dwarf_fpu_##reg##i, \ + eFormatVectorOfUInt8, \ + { gcc_dwarf_fpu_##reg##i, gcc_dwarf_fpu_##reg##i, \ LLDB_INVALID_REGNUM, gdb_fpu_##reg##i, fpu_##reg##i }, NULL, NULL } -#define REG_CONTEXT_SIZE (sizeof(GPR) + sizeof(RegisterContext_x86_64::FPR)) +#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof(RegisterContext_x86_64::FPR)) static RegisterInfo g_register_infos[k_num_registers] = @@ -553,17 +445,7 @@ g_register_infos[k_num_registers] = DEFINE_YMM(ymm, 15) }; -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; -} +RegisterInfo *RegisterContext_x86_64::m_register_infos = g_register_infos; static bool IsGPR(unsigned reg) { @@ -629,6 +511,20 @@ RegisterContext_x86_64::InvalidateAllRegisters() { } +unsigned +RegisterContext_x86_64::GetRegisterOffset(unsigned reg) +{ + assert(reg < k_num_registers && "Invalid register number."); + return GetRegisterInfo()[reg].byte_offset; +} + +unsigned +RegisterContext_x86_64::GetRegisterSize(unsigned reg) +{ + assert(reg < k_num_registers && "Invalid register number."); + return GetRegisterInfo()[reg].byte_size; +} + size_t RegisterContext_x86_64::GetRegisterCount() { @@ -639,10 +535,16 @@ RegisterContext_x86_64::GetRegisterCount() } const RegisterInfo * +RegisterContext_x86_64::GetRegisterInfo() +{ + return m_register_infos; +} + +const RegisterInfo * RegisterContext_x86_64::GetRegisterInfoAtIndex(size_t reg) { if (reg < k_num_registers) - return &g_register_infos[reg]; + return &GetRegisterInfo()[reg]; else return NULL; } @@ -673,7 +575,7 @@ RegisterContext_x86_64::GetRegisterIndexFromOffset(unsigned offset) unsigned reg; for (reg = 0; reg < k_num_registers; reg++) { - if (g_register_infos[reg].byte_offset == offset) + if (m_register_infos[reg].byte_offset == offset) break; } assert(reg < k_num_registers && "Invalid register offset."); @@ -684,7 +586,7 @@ const char * RegisterContext_x86_64::GetRegisterName(unsigned reg) { assert(reg < k_num_registers && "Invalid register offset."); - return g_register_infos[reg].name; + return m_register_infos[reg].name; } lldb::ByteOrder @@ -776,7 +678,7 @@ RegisterContext_x86_64::ReadRegister(const RegisterInfo *reg_info, RegisterValue } else { ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadRegisterValue(m_thread.GetID(), GetRegOffset(reg), GetRegSize(reg), value); + return monitor.ReadRegisterValue(m_thread.GetID(), GetRegisterOffset(reg), GetRegisterSize(reg), value); } if (reg_info->encoding == eEncodingVector) { @@ -845,8 +747,8 @@ RegisterContext_x86_64::ReadAllRegisterValues(DataBufferSP &data_sp) success = dst != 0; if (success) { - ::memcpy (dst, &user.regs, sizeof(user.regs)); - dst += sizeof(user.regs); + ::memcpy (dst, &user.regs, GetGPRSize()); + dst += GetGPRSize(); } if (user.fpr_type == eFXSAVE) ::memcpy (dst, &user.i387.xstate.fxsave, sizeof(user.i387.xstate.fxsave)); @@ -874,7 +776,7 @@ RegisterContext_x86_64::WriteRegister(const lldb_private::RegisterInfo *reg_info const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; if (IsGPR(reg)) { ProcessMonitor &monitor = GetMonitor(); - return monitor.WriteRegisterValue(m_thread.GetID(), GetRegOffset(reg), value); + return monitor.WriteRegisterValue(m_thread.GetID(), GetRegisterOffset(reg), value); } if (IsFPR(reg, user.fpr_type)) { @@ -942,10 +844,10 @@ RegisterContext_x86_64::WriteAllRegisterValues(const DataBufferSP &data_sp) { uint8_t *src = data_sp->GetBytes(); if (src) { - ::memcpy (&user.regs, src, sizeof(user.regs)); + ::memcpy (&user.regs, src, GetGPRSize()); if (WriteGPR()) { - src += sizeof(user.regs); + src += GetGPRSize(); if (user.fpr_type == eFXSAVE) ::memcpy (&user.i387.xstate.fxsave, src, sizeof(user.i387.xstate.fxsave)); if (user.fpr_type == eXSAVE) @@ -1310,7 +1212,7 @@ bool RegisterContext_x86_64::ReadGPR() { ProcessMonitor &monitor = GetMonitor(); - return monitor.ReadGPR(m_thread.GetID(), &user.regs, sizeof(user.regs)); + return monitor.ReadGPR(m_thread.GetID(), &user.regs, GetGPRSize()); } bool @@ -1329,7 +1231,7 @@ bool RegisterContext_x86_64::WriteGPR() { ProcessMonitor &monitor = GetMonitor(); - return monitor.WriteGPR(m_thread.GetID(), &user.regs, sizeof(user.regs)); + return monitor.WriteGPR(m_thread.GetID(), &user.regs, GetGPRSize()); } bool diff --git a/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.h b/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.h index 169ebe00e84..2d7667b5431 100644 --- a/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.h +++ b/lldb/source/Plugins/Process/POSIX/RegisterContext_x86_64.h @@ -13,22 +13,115 @@ #include "lldb/Core/Log.h" #include "RegisterContextPOSIX.h" -#ifdef __FreeBSD__ -#include "RegisterContextFreeBSD_x86_64.h" -#endif - -#ifdef __linux__ -#include "RegisterContextLinux_x86_64.h" -#endif - class ProcessMonitor; +// Internal codes for all x86_64 registers. +enum +{ + k_first_gpr, + gpr_rax = k_first_gpr, + gpr_rbx, + gpr_rcx, + gpr_rdx, + gpr_rdi, + gpr_rsi, + gpr_rbp, + gpr_rsp, + gpr_r8, + gpr_r9, + gpr_r10, + gpr_r11, + gpr_r12, + gpr_r13, + gpr_r14, + gpr_r15, + gpr_rip, + gpr_rflags, + gpr_cs, + gpr_fs, + gpr_gs, + gpr_ss, + gpr_ds, + gpr_es, + gpr_eax, + gpr_ebx, + gpr_ecx, + gpr_edx, + gpr_edi, + gpr_esi, + gpr_ebp, + gpr_esp, + gpr_eip, + gpr_eflags, + k_last_gpr = gpr_eflags, // eRegisterKindLLDB == 33 + + k_first_fpr, + fpu_fcw = k_first_fpr, + fpu_fsw, + fpu_ftw, + fpu_fop, + fpu_ip, + fpu_cs, + fpu_dp, + fpu_ds, + fpu_mxcsr, + fpu_mxcsrmask, + 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, + fpu_xmm8, + fpu_xmm9, + fpu_xmm10, + fpu_xmm11, + fpu_xmm12, + fpu_xmm13, + fpu_xmm14, + fpu_xmm15, + k_last_fpr = fpu_xmm15, + k_first_avx, + fpu_ymm0 = k_first_avx, + fpu_ymm1, + fpu_ymm2, + fpu_ymm3, + fpu_ymm4, + fpu_ymm5, + fpu_ymm6, + fpu_ymm7, + fpu_ymm8, + fpu_ymm9, + fpu_ymm10, + fpu_ymm11, + fpu_ymm12, + fpu_ymm13, + fpu_ymm14, + fpu_ymm15, + k_last_avx = fpu_ymm15, + + k_num_registers, + k_num_gpr_registers = k_last_gpr - k_first_gpr + 1, + k_num_fpr_registers = k_last_fpr - k_first_fpr + 1, + k_num_avx_registers = k_last_avx - k_first_avx + 1 +}; + class RegisterContext_x86_64 : public RegisterContextPOSIX { public: RegisterContext_x86_64 (lldb_private::Thread &thread, - uint32_t concrete_frame_idx); + uint32_t concrete_frame_idx); ~RegisterContext_x86_64(); @@ -41,6 +134,15 @@ public: size_t GetRegisterCount(); + virtual size_t + GetGPRSize() = 0; + + virtual unsigned + GetRegisterSize(unsigned reg); + + virtual unsigned + GetRegisterOffset(unsigned reg); + const lldb_private::RegisterInfo * GetRegisterInfoAtIndex(size_t reg); @@ -174,7 +276,7 @@ public: struct UserArea { - GPR regs; // General purpose registers. + uint64_t regs[k_last_gpr];// General purpose registers. FPRType fpr_type; // Determines the type of data stored by union FPR, if any. int32_t pad0; FPR i387; // Floating point registers. @@ -201,6 +303,12 @@ protected: virtual bool IsRegisterSetAvailable(size_t set_index); + virtual const lldb_private::RegisterInfo * + GetRegisterInfo(); + +private: + static lldb_private::RegisterInfo *m_register_infos; + private: UserArea user; |