aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.cpp')
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.cpp151
1 files changed, 55 insertions, 96 deletions
diff --git a/source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.cpp b/source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.cpp
index c1aea2a41a1f..5434ddfcf38b 100644
--- a/source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.cpp
+++ b/source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextLinux_x86_64.h --------------------------*- C++ -*-===//
+//===-- RegisterContextLinux_x86_64.cpp ------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,36 +7,13 @@
//
//===---------------------------------------------------------------------===//
-#include "llvm/Support/Compiler.h"
-#include "RegisterContextLinux_x86_64.h"
#include <vector>
+#include "RegisterContextPOSIX_x86.h"
+#include "RegisterContextLinux_i386.h"
+#include "RegisterContextLinux_x86_64.h"
using namespace lldb_private;
-
-// Computes the offset of the given GPR in the user data area.
-#define GPR_OFFSET(regname) \
- (offsetof(GPR, regname))
-
-// Update the Linux specific information (offset and size).
-#define UPDATE_GPR_INFO(reg) \
-do { \
- GetRegisterContext()[gpr_##reg].byte_size = sizeof(GPR::reg); \
- GetRegisterContext()[gpr_##reg].byte_offset = GPR_OFFSET(reg); \
-} while(false);
-
-#define UPDATE_I386_GPR_INFO(i386_reg, reg) \
-do { \
- GetRegisterContext()[gpr_##i386_reg].byte_offset = GPR_OFFSET(reg); \
-} while(false);
-
-#define DR_OFFSET(reg_index) \
- (LLVM_EXTENSION offsetof(UserArea, u_debugreg[reg_index]))
-
-#define UPDATE_DR_INFO(reg_index) \
-do { \
- GetRegisterContext()[dr##reg_index].byte_size = sizeof(UserArea::u_debugreg[0]); \
- GetRegisterContext()[dr##reg_index].byte_offset = DR_OFFSET(reg_index); \
-} while(false);
+using namespace lldb;
typedef struct _GPR
{
@@ -69,8 +46,6 @@ typedef struct _GPR
uint64_t gs;
} GPR;
-typedef RegisterContext_x86_64::FXSAVE FXSAVE;
-
struct UserArea
{
GPR gpr; // General purpose registers.
@@ -94,14 +69,48 @@ struct UserArea
uint64_t fault_address; // Control register CR3.
};
-// Use a singleton function to avoid global constructors in shared libraries.
-static std::vector<RegisterInfo> & GetRegisterContext () {
- static std::vector<RegisterInfo> g_register_infos;
- return g_register_infos;
+#define DR_SIZE sizeof(UserArea::u_debugreg[0])
+#define DR_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, u_debugreg[reg_index]))
+
+//---------------------------------------------------------------------------
+// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64 structure.
+//---------------------------------------------------------------------------
+#define DECLARE_REGISTER_INFOS_X86_64_STRUCT
+#include "RegisterInfos_x86_64.h"
+#undef DECLARE_REGISTER_INFOS_X86_64_STRUCT
+
+static const RegisterInfo *
+GetRegisterInfo_i386(const lldb_private::ArchSpec &arch)
+{
+ static std::vector<lldb_private::RegisterInfo> g_register_infos;
+
+ // Allocate RegisterInfo only once
+ if (g_register_infos.empty())
+ {
+ // Copy the register information from base class
+ std::unique_ptr<RegisterContextLinux_i386> reg_interface(new RegisterContextLinux_i386 (arch));
+ const RegisterInfo *base_info = reg_interface->GetRegisterInfo();
+ g_register_infos.insert(g_register_infos.end(), &base_info[0], &base_info[k_num_registers_i386]);
+
+ //---------------------------------------------------------------------------
+ // Include RegisterInfos_x86_64 to update the g_register_infos structure
+ // with x86_64 offsets.
+ //---------------------------------------------------------------------------
+ #define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
+ #include "RegisterInfos_x86_64.h"
+ #undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
+ }
+
+ return &g_register_infos[0];
+}
+
+RegisterContextLinux_x86_64::RegisterContextLinux_x86_64(const ArchSpec &target_arch) :
+ RegisterInfoInterface(target_arch)
+{
}
-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()
{
}
@@ -114,67 +123,17 @@ RegisterContextLinux_x86_64::GetGPRSize()
const RegisterInfo *
RegisterContextLinux_x86_64::GetRegisterInfo()
{
- // Allocate RegisterInfo only once
- if (GetRegisterContext().empty())
+ switch (m_target_arch.GetCore())
{
- // Copy the register information from base class
- const RegisterInfo *base_info = RegisterContext_x86_64::GetRegisterInfo();
- if (base_info)
- {
- GetRegisterContext().insert(GetRegisterContext().end(), &base_info[0], &base_info[k_num_registers]);
- // Update the Linux specific register information (offset and size).
- UpdateRegisterInfo();
- }
+ case ArchSpec::eCore_x86_32_i386:
+ case ArchSpec::eCore_x86_32_i486:
+ case ArchSpec::eCore_x86_32_i486sx:
+ return GetRegisterInfo_i386 (m_target_arch);
+ case ArchSpec::eCore_x86_64_x86_64:
+ return g_register_infos_x86_64;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
}
- return &GetRegisterContext()[0];
-}
-
-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);
-
- UPDATE_DR_INFO(0);
- UPDATE_DR_INFO(1);
- UPDATE_DR_INFO(2);
- UPDATE_DR_INFO(3);
- UPDATE_DR_INFO(4);
- UPDATE_DR_INFO(5);
- UPDATE_DR_INFO(6);
- UPDATE_DR_INFO(7);
}