aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/Process/POSIX
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/Process/POSIX')
-rw-r--r--source/Plugins/Process/POSIX/POSIXThread.cpp156
-rw-r--r--source/Plugins/Process/POSIX/POSIXThread.h16
-rw-r--r--source/Plugins/Process/POSIX/ProcessMessage.cpp6
-rw-r--r--source/Plugins/Process/POSIX/ProcessMessage.h14
-rw-r--r--source/Plugins/Process/POSIX/ProcessPOSIX.cpp103
-rw-r--r--source/Plugins/Process/POSIX/ProcessPOSIX.h8
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextFreeBSD_i386.cpp78
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextFreeBSD_i386.h29
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextFreeBSD_mips64.cpp90
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextFreeBSD_mips64.h29
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.cpp129
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.h15
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextLinux_i386.cpp96
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextLinux_i386.h29
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.cpp151
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.h15
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextPOSIX.h50
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.cpp318
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.h95
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.cpp634
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.h95
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.cpp238
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h138
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextPOSIX_x86.cpp666
-rw-r--r--source/Plugins/Process/POSIX/RegisterContextPOSIX_x86.h462
-rw-r--r--source/Plugins/Process/POSIX/RegisterContext_i386.cpp551
-rw-r--r--source/Plugins/Process/POSIX/RegisterContext_i386.h169
-rw-r--r--source/Plugins/Process/POSIX/RegisterContext_mips64.h104
-rw-r--r--source/Plugins/Process/POSIX/RegisterContext_x86.h541
-rw-r--r--source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp1563
-rw-r--r--source/Plugins/Process/POSIX/RegisterContext_x86_64.h347
-rw-r--r--source/Plugins/Process/POSIX/RegisterInfos_i386.h207
-rw-r--r--source/Plugins/Process/POSIX/RegisterInfos_mips64.h74
-rw-r--r--source/Plugins/Process/POSIX/RegisterInfos_x86_64.h409
34 files changed, 4607 insertions, 3018 deletions
diff --git a/source/Plugins/Process/POSIX/POSIXThread.cpp b/source/Plugins/Process/POSIX/POSIXThread.cpp
index 93c296679df2..16399748c544 100644
--- a/source/Plugins/Process/POSIX/POSIXThread.cpp
+++ b/source/Plugins/Process/POSIX/POSIXThread.cpp
@@ -29,10 +29,12 @@
#include "ProcessPOSIX.h"
#include "ProcessPOSIXLog.h"
#include "ProcessMonitor.h"
-#include "RegisterContext_i386.h"
-#include "RegisterContext_x86_64.h"
-#include "RegisterContextPOSIX.h"
+#include "RegisterContextPOSIXProcessMonitor_mips64.h"
+#include "RegisterContextPOSIXProcessMonitor_x86.h"
+#include "RegisterContextLinux_i386.h"
#include "RegisterContextLinux_x86_64.h"
+#include "RegisterContextFreeBSD_i386.h"
+#include "RegisterContextFreeBSD_mips64.h"
#include "RegisterContextFreeBSD_x86_64.h"
#include "UnwindLLDB.h"
@@ -46,7 +48,8 @@ POSIXThread::POSIXThread(Process &process, lldb::tid_t tid)
m_frame_ap (),
m_breakpoint (),
m_thread_name_valid (false),
- m_thread_name ()
+ m_thread_name (),
+ m_posix_thread(NULL)
{
Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
@@ -138,34 +141,66 @@ POSIXThread::GetRegisterContext()
{
if (!m_reg_context_sp)
{
- ArchSpec arch = Host::GetArchitecture();
+ m_posix_thread = NULL;
- switch (arch.GetCore())
+ RegisterInfoInterface *reg_interface = NULL;
+ const ArchSpec &target_arch = GetProcess()->GetTarget().GetArchitecture();
+
+ switch (target_arch.GetCore())
{
- default:
- 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 RegisterContext_i386(*this, 0));
- break;
-
- case ArchSpec::eCore_x86_64_x86_64:
- switch (arch.GetTriple().getOS())
+ case ArchSpec::eCore_mips64:
{
- case llvm::Triple::FreeBSD:
- m_reg_context_sp.reset(new RegisterContextFreeBSD_x86_64(*this, 0));
- break;
- case llvm::Triple::Linux:
- m_reg_context_sp.reset(new RegisterContextLinux_x86_64(*this, 0));
- break;
- default:
- assert(false && "OS not supported");
- break;
+ RegisterInfoInterface *reg_interface = NULL;
+
+ switch (target_arch.GetTriple().getOS())
+ {
+ case llvm::Triple::FreeBSD:
+ reg_interface = new RegisterContextFreeBSD_mips64(target_arch);
+ break;
+ default:
+ assert(false && "OS not supported");
+ break;
+ }
+
+ if (reg_interface)
+ {
+ RegisterContextPOSIXProcessMonitor_mips64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_mips64(*this, 0, reg_interface);
+ m_posix_thread = reg_ctx;
+ m_reg_context_sp.reset(reg_ctx);
+ }
+ break;
}
- break;
+
+ case ArchSpec::eCore_x86_32_i386:
+ case ArchSpec::eCore_x86_32_i486:
+ case ArchSpec::eCore_x86_32_i486sx:
+ case ArchSpec::eCore_x86_64_x86_64:
+ {
+ switch (target_arch.GetTriple().getOS())
+ {
+ case llvm::Triple::FreeBSD:
+ reg_interface = new RegisterContextFreeBSD_x86_64(target_arch);
+ break;
+ case llvm::Triple::Linux:
+ reg_interface = new RegisterContextLinux_x86_64(target_arch);
+ break;
+ default:
+ assert(false && "OS not supported");
+ break;
+ }
+
+ if (reg_interface)
+ {
+ RegisterContextPOSIXProcessMonitor_x86_64 *reg_ctx = new RegisterContextPOSIXProcessMonitor_x86_64(*this, 0, reg_interface);
+ m_posix_thread = reg_ctx;
+ m_reg_context_sp.reset(reg_ctx);
+ }
+ break;
+ }
+
+ default:
+ assert(false && "CPU type not supported!");
+ break;
}
}
return m_reg_context_sp;
@@ -195,6 +230,17 @@ POSIXThread::CreateRegisterContextForFrame(lldb_private::StackFrame *frame)
return reg_ctx_sp;
}
+lldb::addr_t
+POSIXThread::GetThreadPointer ()
+{
+ ProcessMonitor &monitor = GetMonitor();
+ addr_t addr;
+ if (monitor.ReadThreadPointer (GetID(), addr))
+ return addr;
+ else
+ return LLDB_INVALID_ADDRESS;
+}
+
bool
POSIXThread::CalculateStopInfo()
{
@@ -314,6 +360,10 @@ POSIXThread::Notify(const ProcessMessage &message)
case ProcessMessage::eNewThreadMessage:
ThreadNotify(message);
break;
+
+ case ProcessMessage::eExecMessage:
+ ExecNotify(message);
+ break;
}
}
@@ -328,7 +378,7 @@ POSIXThread::EnableHardwareWatchpoint(Watchpoint *wp)
bool wp_read = wp->WatchpointRead();
bool wp_write = wp->WatchpointWrite();
uint32_t wp_hw_index = wp->GetHardwareIndex();
- RegisterContextPOSIX* reg_ctx = GetRegisterContextPOSIX();
+ POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
if (reg_ctx)
wp_set = reg_ctx->SetHardwareWatchpointWithIndex(wp_addr, wp_size,
wp_read, wp_write,
@@ -365,7 +415,7 @@ POSIXThread::FindVacantWatchpointIndex()
uint32_t hw_index = LLDB_INVALID_INDEX32;
uint32_t num_hw_wps = NumSupportedHardwareWatchpoints();
uint32_t wp_idx;
- RegisterContextPOSIX* reg_ctx = GetRegisterContextPOSIX();
+ POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
if (reg_ctx)
{
for (wp_idx = 0; wp_idx < num_hw_wps; wp_idx++)
@@ -387,7 +437,7 @@ POSIXThread::BreakNotify(const ProcessMessage &message)
Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
assert(GetRegisterContext());
- status = GetRegisterContextPOSIX()->UpdateAfterBreakpoint();
+ status = GetPOSIXBreakpointProtocol()->UpdateAfterBreakpoint();
assert(status && "Breakpoint update failed!");
// With our register state restored, resolve the breakpoint object
@@ -399,31 +449,22 @@ POSIXThread::BreakNotify(const ProcessMessage &message)
lldb::BreakpointSiteSP bp_site(GetProcess()->GetBreakpointSiteList().FindByAddress(pc));
// If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
- // we can just report no reason. We don't need to worry about stepping over the breakpoint here, that
- // will be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
- if (bp_site && bp_site->ValidForThisThread(this))
+ // we create a stop reason with should_stop=false. If there is no breakpoint location, then report
+ // an invalid stop reason. We don't need to worry about stepping over the breakpoint here, that will
+ // be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
+ if (bp_site)
{
lldb::break_id_t bp_id = bp_site->GetID();
- if (GetProcess()->GetThreadList().SetSelectedThreadByID(GetID()))
+ if (bp_site->ValidForThisThread(this))
SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id));
else
- assert(false && "Invalid thread ID during BreakNotify.");
- }
- else
- {
- const ThreadSpec *spec = bp_site ?
- bp_site->GetOwnerAtIndex(0)->GetOptionsNoCreate()->GetThreadSpecNoCreate() : 0;
-
- if (spec && spec->TIDMatches(*this))
- assert(false && "BreakpointSite is invalid for the current ThreadSpec.");
- else
{
- if (!m_stop_info_sp) {
- StopInfoSP invalid_stop_info_sp;
- SetStopInfo (invalid_stop_info_sp);
- }
+ const bool should_stop = false;
+ SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID(*this, bp_id, should_stop));
}
}
+ else
+ SetStopInfo(StopInfoSP());
}
void
@@ -436,7 +477,7 @@ POSIXThread::WatchNotify(const ProcessMessage &message)
log->Printf ("POSIXThread::%s () Hardware Watchpoint Address = 0x%8.8"
PRIx64, __FUNCTION__, halt_addr);
- RegisterContextPOSIX* reg_ctx = GetRegisterContextPOSIX();
+ POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
if (reg_ctx)
{
uint32_t num_hw_wps = reg_ctx->NumSupportedHardwareWatchpoints();
@@ -532,22 +573,26 @@ POSIXThread::GetRegisterIndexFromOffset(unsigned offset)
llvm_unreachable("CPU type not supported!");
break;
+ case ArchSpec::eCore_mips64:
case ArchSpec::eCore_x86_32_i386:
case ArchSpec::eCore_x86_32_i486:
case ArchSpec::eCore_x86_32_i486sx:
case ArchSpec::eCore_x86_64_x86_64:
{
- RegisterContextSP base = GetRegisterContext();
- if (base) {
- RegisterContextPOSIX &context = static_cast<RegisterContextPOSIX &>(*base);
- reg = context.GetRegisterIndexFromOffset(offset);
- }
+ POSIXBreakpointProtocol* reg_ctx = GetPOSIXBreakpointProtocol();
+ reg = reg_ctx->GetRegisterIndexFromOffset(offset);
}
break;
}
return reg;
}
+void
+POSIXThread::ExecNotify(const ProcessMessage &message)
+{
+ SetStopInfo (StopInfo::CreateStopReasonWithExec(*this));
+}
+
const char *
POSIXThread::GetRegisterName(unsigned reg)
{
@@ -560,6 +605,7 @@ POSIXThread::GetRegisterName(unsigned reg)
assert(false && "CPU type not supported!");
break;
+ case ArchSpec::eCore_mips64:
case ArchSpec::eCore_x86_32_i386:
case ArchSpec::eCore_x86_32_i486:
case ArchSpec::eCore_x86_32_i486sx:
diff --git a/source/Plugins/Process/POSIX/POSIXThread.h b/source/Plugins/Process/POSIX/POSIXThread.h
index d051d23860df..51d6645f209d 100644
--- a/source/Plugins/Process/POSIX/POSIXThread.h
+++ b/source/Plugins/Process/POSIX/POSIXThread.h
@@ -21,7 +21,7 @@
class ProcessMessage;
class ProcessMonitor;
-class RegisterContextPOSIX;
+class POSIXBreakpointProtocol;
//------------------------------------------------------------------------------
// @class POSIXThread
@@ -59,6 +59,9 @@ public:
virtual lldb::RegisterContextSP
CreateRegisterContextForFrame (lldb_private::StackFrame *frame);
+ virtual lldb::addr_t
+ GetThreadPointer ();
+
//--------------------------------------------------------------------------
// These functions provide a mapping from the register offset
// back to the register index or name for use in debugging or log
@@ -92,15 +95,12 @@ public:
uint32_t FindVacantWatchpointIndex();
protected:
- RegisterContextPOSIX *
- GetRegisterContextPOSIX ()
+ POSIXBreakpointProtocol *
+ GetPOSIXBreakpointProtocol ()
{
if (!m_reg_context_sp)
m_reg_context_sp = GetRegisterContext();
-#if 0
- return dynamic_cast<RegisterContextPOSIX*>(m_reg_context_sp.get());
-#endif
- return (RegisterContextPOSIX *)m_reg_context_sp.get();
+ return m_posix_thread;
}
std::unique_ptr<lldb_private::StackFrame> m_frame_ap;
@@ -109,6 +109,7 @@ protected:
bool m_thread_name_valid;
std::string m_thread_name;
+ POSIXBreakpointProtocol *m_posix_thread;
ProcessMonitor &
GetMonitor();
@@ -125,6 +126,7 @@ protected:
void CrashNotify(const ProcessMessage &message);
void ThreadNotify(const ProcessMessage &message);
void ExitNotify(const ProcessMessage &message);
+ void ExecNotify(const ProcessMessage &message);
lldb_private::Unwind *
GetUnwinder();
diff --git a/source/Plugins/Process/POSIX/ProcessMessage.cpp b/source/Plugins/Process/POSIX/ProcessMessage.cpp
index 60a29e07cea8..5c53627f9e0b 100644
--- a/source/Plugins/Process/POSIX/ProcessMessage.cpp
+++ b/source/Plugins/Process/POSIX/ProcessMessage.cpp
@@ -218,6 +218,9 @@ ProcessMessage::PrintKind(Kind kind)
case eInvalidMessage:
str = "eInvalidMessage";
break;
+ case eAttachMessage:
+ str = "eAttachMessage";
+ break;
case eExitMessage:
str = "eExitMessage";
break;
@@ -245,6 +248,9 @@ ProcessMessage::PrintKind(Kind kind)
case eNewThreadMessage:
str = "eNewThreadMessage";
break;
+ case eExecMessage:
+ str = "eExecMessage";
+ break;
}
#endif
diff --git a/source/Plugins/Process/POSIX/ProcessMessage.h b/source/Plugins/Process/POSIX/ProcessMessage.h
index c6c460c13445..40462d0f0e13 100644
--- a/source/Plugins/Process/POSIX/ProcessMessage.h
+++ b/source/Plugins/Process/POSIX/ProcessMessage.h
@@ -23,6 +23,7 @@ public:
enum Kind
{
eInvalidMessage,
+ eAttachMessage,
eExitMessage,
eLimboMessage,
eSignalMessage,
@@ -31,7 +32,8 @@ public:
eBreakpointMessage,
eWatchpointMessage,
eCrashMessage,
- eNewThreadMessage
+ eNewThreadMessage,
+ eExecMessage
};
enum CrashReason
@@ -79,6 +81,11 @@ public:
lldb::tid_t GetTID() const { return m_tid; }
+ /// Indicates that the process @p pid has successfully attached.
+ static ProcessMessage Attach(lldb::pid_t pid) {
+ return ProcessMessage(pid, eAttachMessage);
+ }
+
/// Indicates that the thread @p tid is about to exit with status @p status.
static ProcessMessage Limbo(lldb::tid_t tid, int status) {
return ProcessMessage(tid, eLimboMessage, status);
@@ -127,6 +134,11 @@ public:
return ProcessMessage(tid, eExitMessage, status);
}
+ /// Indicates that the thread @p pid has exec'd.
+ static ProcessMessage Exec(lldb::tid_t tid) {
+ return ProcessMessage(tid, eExecMessage);
+ }
+
int GetExitStatus() const {
assert(GetKind() == eExitMessage || GetKind() == eLimboMessage);
return m_status;
diff --git a/source/Plugins/Process/POSIX/ProcessPOSIX.cpp b/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
index f04631ddf914..70ad3a66d9ef 100644
--- a/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
+++ b/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
@@ -289,12 +289,11 @@ ProcessPOSIX::GetImageInfoAddress()
{
Target *target = &GetTarget();
ObjectFile *obj_file = target->GetExecutableModule()->GetObjectFile();
- Address addr = obj_file->GetImageInfoAddress();
+ Address addr = obj_file->GetImageInfoAddress(target);
- if (addr.IsValid())
+ if (addr.IsValid())
return addr.GetLoadAddress(target);
- else
- return LLDB_INVALID_ADDRESS;
+ return LLDB_INVALID_ADDRESS;
}
Error
@@ -319,34 +318,6 @@ ProcessPOSIX::DoHalt(bool &caused_stop)
}
Error
-ProcessPOSIX::DoDetach(bool keep_stopped)
-{
- Error error;
- if (keep_stopped)
- {
- // FIXME: If you want to implement keep_stopped,
- // this would be the place to do it.
- error.SetErrorString("Detaching with keep_stopped true is not currently supported on this platform.");
- return error;
- }
-
- Mutex::Locker lock(m_thread_list.GetMutex());
-
- uint32_t thread_count = m_thread_list.GetSize(false);
- for (uint32_t i = 0; i < thread_count; ++i)
- {
- POSIXThread *thread = static_cast<POSIXThread*>(
- m_thread_list.GetThreadAtIndex(i, false).get());
- error = m_monitor->Detach(thread->GetID());
- }
-
- if (error.Success())
- SetPrivateState(eStateDetached);
-
- return error;
-}
-
-Error
ProcessPOSIX::DoSignal(int signal)
{
Error error;
@@ -381,6 +352,31 @@ ProcessPOSIX::DoDestroy()
}
void
+ProcessPOSIX::DoDidExec()
+{
+ Target *target = &GetTarget();
+ if (target)
+ {
+ PlatformSP platform_sp (target->GetPlatform());
+ assert (platform_sp.get());
+ if (platform_sp)
+ {
+ ProcessInstanceInfo process_info;
+ platform_sp->GetProcessInfo(GetID(), process_info);
+ ModuleSP exe_module_sp;
+ FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
+ Error error = platform_sp->ResolveExecutable(process_info.GetExecutableFile(),
+ target->GetArchitecture(),
+ exe_module_sp,
+ executable_search_paths.GetSize() ? &executable_search_paths : NULL);
+ if (!error.Success())
+ return;
+ target->SetExecutableModule(exe_module_sp, true);
+ }
+ }
+}
+
+void
ProcessPOSIX::SendMessage(const ProcessMessage &message)
{
Mutex::Locker lock(m_message_mutex);
@@ -395,6 +391,10 @@ ProcessPOSIX::SendMessage(const ProcessMessage &message)
case ProcessMessage::eInvalidMessage:
return;
+ case ProcessMessage::eAttachMessage:
+ SetPrivateState(eStateStopped);
+ return;
+
case ProcessMessage::eLimboMessage:
assert(thread);
thread->SetState(eStateStopped);
@@ -442,15 +442,38 @@ ProcessPOSIX::SendMessage(const ProcessMessage &message)
case ProcessMessage::eBreakpointMessage:
case ProcessMessage::eTraceMessage:
case ProcessMessage::eWatchpointMessage:
- case ProcessMessage::eNewThreadMessage:
case ProcessMessage::eCrashMessage:
assert(thread);
thread->SetState(eStateStopped);
StopAllThreads(message.GetTID());
SetPrivateState(eStateStopped);
break;
+
+ case ProcessMessage::eNewThreadMessage:
+ {
+ lldb::tid_t new_tid = message.GetChildTID();
+ if (WaitingForInitialStop(new_tid))
+ {
+ m_monitor->WaitForInitialTIDStop(new_tid);
+ }
+ assert(thread);
+ thread->SetState(eStateStopped);
+ StopAllThreads(message.GetTID());
+ SetPrivateState(eStateStopped);
+ break;
}
+ case ProcessMessage::eExecMessage:
+ {
+ assert(thread);
+ thread->SetState(eStateStopped);
+ StopAllThreads(message.GetTID());
+ SetPrivateState(eStateStopped);
+ break;
+ }
+ }
+
+
m_message_queue.push(message);
}
@@ -473,6 +496,12 @@ ProcessPOSIX::AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid)
return added_to_set;
}
+bool
+ProcessPOSIX::WaitingForInitialStop(lldb::tid_t stop_tid)
+{
+ return (m_seen_initial_stop.find(stop_tid) == m_seen_initial_stop.end());
+}
+
POSIXThread *
ProcessPOSIX::CreateNewPOSIXThread(lldb_private::Process &process, lldb::tid_t tid)
{
@@ -499,8 +528,6 @@ ProcessPOSIX::RefreshStateAfterStop()
lldb::tid_t tid = message.GetTID();
if (log)
log->Printf ("ProcessPOSIX::%s(), message_queue size = %d, pid = %" PRIi64, __FUNCTION__, (int)m_message_queue.size(), tid);
- POSIXThread *thread = static_cast<POSIXThread*>(
- GetThreadList().FindThreadByID(tid, false).get());
if (message.GetKind() == ProcessMessage::eNewThreadMessage)
{
@@ -517,6 +544,8 @@ ProcessPOSIX::RefreshStateAfterStop()
m_thread_list.RefreshStateAfterStop();
+ POSIXThread *thread = static_cast<POSIXThread*>(
+ GetThreadList().FindThreadByID(tid, false).get());
if (thread)
thread->Notify(message);
@@ -813,19 +842,21 @@ ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thre
if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
+ bool has_updated = false;
// Update the process thread list with this new thread.
// FIXME: We should be using tid, not pid.
assert(m_monitor);
ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
if (!thread_sp) {
thread_sp.reset(CreateNewPOSIXThread(*this, GetID()));
+ has_updated = true;
}
if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
log->Printf ("ProcessPOSIX::%s() updated pid = %" PRIi64, __FUNCTION__, GetID());
new_thread_list.AddThread(thread_sp);
- return new_thread_list.GetSize(false) > 0;
+ return has_updated; // the list has been updated
}
ByteOrder
diff --git a/source/Plugins/Process/POSIX/ProcessPOSIX.h b/source/Plugins/Process/POSIX/ProcessPOSIX.h
index 48b19bac47e7..790041be321a 100644
--- a/source/Plugins/Process/POSIX/ProcessPOSIX.h
+++ b/source/Plugins/Process/POSIX/ProcessPOSIX.h
@@ -70,7 +70,7 @@ public:
DoHalt(bool &caused_stop);
virtual lldb_private::Error
- DoDetach(bool keep_stopped);
+ DoDetach(bool keep_stopped) = 0;
virtual lldb_private::Error
DoSignal(int signal);
@@ -79,6 +79,9 @@ public:
DoDestroy();
virtual void
+ DoDidExec();
+
+ virtual void
RefreshStateAfterStop();
virtual bool
@@ -167,6 +170,9 @@ public:
bool
AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid);
+ bool
+ WaitingForInitialStop(lldb::tid_t stop_tid);
+
virtual POSIXThread *
CreateNewPOSIXThread(lldb_private::Process &process, lldb::tid_t tid);
diff --git a/source/Plugins/Process/POSIX/RegisterContextFreeBSD_i386.cpp b/source/Plugins/Process/POSIX/RegisterContextFreeBSD_i386.cpp
new file mode 100644
index 000000000000..50ec8d414a12
--- /dev/null
+++ b/source/Plugins/Process/POSIX/RegisterContextFreeBSD_i386.cpp
@@ -0,0 +1,78 @@
+//===-- RegisterContextFreeBSD_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 "RegisterContextPOSIX_x86.h"
+#include "RegisterContextFreeBSD_i386.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+// http://svnweb.freebsd.org/base/head/sys/x86/include/reg.h
+struct GPR
+{
+ uint32_t fs;
+ uint32_t es;
+ uint32_t ds;
+ uint32_t edi;
+ uint32_t esi;
+ uint32_t ebp;
+ uint32_t isp;
+ uint32_t ebx;
+ uint32_t edx;
+ uint32_t ecx;
+ uint32_t eax;
+ uint32_t trapno;
+ uint32_t err;
+ uint32_t eip;
+ uint32_t cs;
+ uint32_t eflags;
+ uint32_t esp;
+ uint32_t ss;
+ uint32_t gs;
+};
+
+#define DR_SIZE 0
+#define DR_OFFSET(reg_index) 0
+
+//---------------------------------------------------------------------------
+// Include RegisterInfos_i386 to declare our g_register_infos_i386 structure.
+//---------------------------------------------------------------------------
+#define DECLARE_REGISTER_INFOS_I386_STRUCT
+#include "RegisterInfos_i386.h"
+#undef DECLARE_REGISTER_INFOS_I386_STRUCT
+
+RegisterContextFreeBSD_i386::RegisterContextFreeBSD_i386(const ArchSpec &target_arch) :
+ RegisterInfoInterface(target_arch)
+{
+}
+
+RegisterContextFreeBSD_i386::~RegisterContextFreeBSD_i386()
+{
+}
+
+size_t
+RegisterContextFreeBSD_i386::GetGPRSize()
+{
+ return sizeof(GPR);
+}
+
+const RegisterInfo *
+RegisterContextFreeBSD_i386::GetRegisterInfo()
+{
+ switch (m_target_arch.GetCore())
+ {
+ case ArchSpec::eCore_x86_32_i386:
+ case ArchSpec::eCore_x86_32_i486:
+ case ArchSpec::eCore_x86_32_i486sx:
+ return g_register_infos_i386;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
+ }
+}
diff --git a/source/Plugins/Process/POSIX/RegisterContextFreeBSD_i386.h b/source/Plugins/Process/POSIX/RegisterContextFreeBSD_i386.h
new file mode 100644
index 000000000000..4ec2ad3e9706
--- /dev/null
+++ b/source/Plugins/Process/POSIX/RegisterContextFreeBSD_i386.h
@@ -0,0 +1,29 @@
+//===-- RegisterContextFreeBSD_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_RegisterContextFreeBSD_i386_H_
+#define liblldb_RegisterContextFreeBSD_i386_H_
+
+#include "RegisterContextPOSIX.h"
+
+class RegisterContextFreeBSD_i386
+ : public RegisterInfoInterface
+{
+public:
+ RegisterContextFreeBSD_i386(const lldb_private::ArchSpec &target_arch);
+ virtual ~RegisterContextFreeBSD_i386();
+
+ size_t
+ GetGPRSize();
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfo();
+};
+
+#endif
diff --git a/source/Plugins/Process/POSIX/RegisterContextFreeBSD_mips64.cpp b/source/Plugins/Process/POSIX/RegisterContextFreeBSD_mips64.cpp
new file mode 100644
index 000000000000..4714251fd2dc
--- /dev/null
+++ b/source/Plugins/Process/POSIX/RegisterContextFreeBSD_mips64.cpp
@@ -0,0 +1,90 @@
+//===-- RegisterContextFreeBSD_mips64.cpp ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+
+#include <vector>
+#include "RegisterContextPOSIX_mips64.h"
+#include "RegisterContextFreeBSD_mips64.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+// http://svnweb.freebsd.org/base/head/sys/mips/include/regnum.h
+typedef struct _GPR
+{
+ uint64_t zero;
+ uint64_t r1;
+ uint64_t r2;
+ uint64_t r3;
+ uint64_t r4;
+ uint64_t r5;
+ uint64_t r6;
+ uint64_t r7;
+ uint64_t r8;
+ uint64_t r9;
+ uint64_t r10;
+ uint64_t r11;
+ uint64_t r12;
+ uint64_t r13;
+ uint64_t r14;
+ uint64_t r15;
+ uint64_t r16;
+ uint64_t r17;
+ uint64_t r18;
+ uint64_t r19;
+ uint64_t r20;
+ uint64_t r21;
+ uint64_t r22;
+ uint64_t r23;
+ uint64_t r24;
+ uint64_t r25;
+ uint64_t r26;
+ uint64_t r27;
+ uint64_t gp;
+ uint64_t sp;
+ uint64_t r30;
+ uint64_t ra;
+ uint64_t sr;
+ uint64_t mullo;
+ uint64_t mulhi;
+ uint64_t badvaddr;
+ uint64_t cause;
+ uint64_t pc;
+ uint64_t ic;
+ uint64_t dummy;
+} GPR;
+
+//---------------------------------------------------------------------------
+// Include RegisterInfos_mips64 to declare our g_register_infos_mips64 structure.
+//---------------------------------------------------------------------------
+#define DECLARE_REGISTER_INFOS_MIPS64_STRUCT
+#include "RegisterInfos_mips64.h"
+#undef DECLARE_REGISTER_INFOS_MIPS64_STRUCT
+
+RegisterContextFreeBSD_mips64::RegisterContextFreeBSD_mips64(const ArchSpec &target_arch) :
+ RegisterInfoInterface(target_arch)
+{
+}
+
+RegisterContextFreeBSD_mips64::~RegisterContextFreeBSD_mips64()
+{
+}
+
+size_t
+RegisterContextFreeBSD_mips64::GetGPRSize()
+{
+ return sizeof(GPR);
+}
+
+const RegisterInfo *
+RegisterContextFreeBSD_mips64::GetRegisterInfo()
+{
+ assert (m_target_arch.GetCore() == ArchSpec::eCore_mips64);
+ return g_register_infos_mips64;
+}
+
diff --git a/source/Plugins/Process/POSIX/RegisterContextFreeBSD_mips64.h b/source/Plugins/Process/POSIX/RegisterContextFreeBSD_mips64.h
new file mode 100644
index 000000000000..9ee767955347
--- /dev/null
+++ b/source/Plugins/Process/POSIX/RegisterContextFreeBSD_mips64.h
@@ -0,0 +1,29 @@
+//===-- RegisterContextFreeBSD_mips64.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_mips64_H_
+#define liblldb_RegisterContextFreeBSD_mips64_H_
+
+#include "RegisterContextPOSIX.h"
+
+class RegisterContextFreeBSD_mips64:
+ public RegisterInfoInterface
+{
+public:
+ RegisterContextFreeBSD_mips64(const lldb_private::ArchSpec &target_arch);
+ virtual ~RegisterContextFreeBSD_mips64();
+
+ size_t
+ GetGPRSize();
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfo();
+};
+
+#endif
diff --git a/source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.cpp b/source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.cpp
index 0fb9dc1cb3dc..471734580fff 100644
--- a/source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.cpp
+++ b/source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.cpp
@@ -1,4 +1,4 @@
-//===-- RegisterContextFreeBSD_x86_64.h ------------------------*- C++ -*-===//
+//===-- RegisterContextFreeBSD_x86_64.cpp ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,27 +7,15 @@
//
//===---------------------------------------------------------------------===//
-#include "RegisterContextFreeBSD_x86_64.h"
#include <vector>
+#include "RegisterContextPOSIX_x86.h"
+#include "RegisterContextFreeBSD_i386.h"
+#include "RegisterContextFreeBSD_x86_64.h"
using namespace lldb_private;
+using namespace lldb;
-// Computes the offset of the given GPR in the user data area.
-#define GPR_OFFSET(regname) \
- (offsetof(GPR, regname))
-
-// Update the FreeBSD 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);
-
+// http://svnweb.freebsd.org/base/head/sys/x86/include/reg.h
typedef struct _GPR
{
uint64_t r15;
@@ -58,15 +46,47 @@ typedef struct _GPR
uint64_t ss;
} GPR;
-// 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 0
+#define DR_OFFSET(reg_index) 0
+
+//---------------------------------------------------------------------------
+// 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<RegisterContextFreeBSD_i386> reg_interface(new RegisterContextFreeBSD_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];
}
+RegisterContextFreeBSD_x86_64::RegisterContextFreeBSD_x86_64(const ArchSpec &target_arch) :
+ RegisterInfoInterface(target_arch)
+{
+}
-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()
{
}
@@ -79,58 +99,17 @@ RegisterContextFreeBSD_x86_64::GetGPRSize()
const RegisterInfo *
RegisterContextFreeBSD_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 FreeBSD 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
-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/source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.h b/source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.h
index ffff40a9c65b..731bb0ea6bcc 100644
--- a/source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.h
+++ b/source/Plugins/Process/POSIX/RegisterContextFreeBSD_x86_64.h
@@ -1,4 +1,4 @@
-//===-- RegisterContextFreeBSD_x86_64.h ---------------------------*- C++ -*-===//
+//===-- RegisterContextFreeBSD_x86_64.h -------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,23 +10,20 @@
#ifndef liblldb_RegisterContextFreeBSD_x86_64_H_
#define liblldb_RegisterContextFreeBSD_x86_64_H_
-#include "Plugins/Process/POSIX/RegisterContext_x86_64.h"
+#include "RegisterContextPOSIX.h"
class RegisterContextFreeBSD_x86_64:
- public RegisterContext_x86_64
+ public RegisterInfoInterface
{
public:
- RegisterContextFreeBSD_x86_64(lldb_private::Thread &thread, uint32_t concrete_frame_idx);
+ RegisterContextFreeBSD_x86_64(const lldb_private::ArchSpec &target_arch);
+ virtual ~RegisterContextFreeBSD_x86_64();
size_t
GetGPRSize();
-protected:
- virtual const lldb_private::RegisterInfo *
+ const lldb_private::RegisterInfo *
GetRegisterInfo();
-
- virtual void
- UpdateRegisterInfo();
};
#endif
diff --git a/source/Plugins/Process/POSIX/RegisterContextLinux_i386.cpp b/source/Plugins/Process/POSIX/RegisterContextLinux_i386.cpp
new file mode 100644
index 000000000000..0828efbc6c3c
--- /dev/null
+++ b/source/Plugins/Process/POSIX/RegisterContextLinux_i386.cpp
@@ -0,0 +1,96 @@
+//===-- 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 "RegisterContextPOSIX_x86.h"
+#include "RegisterContextLinux_i386.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+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 UserArea
+{
+ GPR regs; // General purpose registers.
+ int32_t fpvalid; // True if FPU is being used.
+ FXSAVE 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.
+ uint32_t fpstate; // Location of FPR's. Should be a FXSTATE *, but this
+ // has to be 32-bits even on 64-bit systems.
+ uint32_t magic; // Identifier for core dumps.
+ char u_comm[32]; // Command causing core dump.
+ uint32_t u_debugreg[8]; // Debug registers (DR0 - DR7).
+};
+
+#define DR_SIZE sizeof(UserArea::u_debugreg[0])
+#define DR_OFFSET(reg_index) \
+ (LLVM_EXTENSION offsetof(UserArea, u_debugreg[reg_index]))
+
+//---------------------------------------------------------------------------
+// Include RegisterInfos_i386 to declare our g_register_infos_i386 structure.
+//---------------------------------------------------------------------------
+#define DECLARE_REGISTER_INFOS_I386_STRUCT
+#include "RegisterInfos_i386.h"
+#undef DECLARE_REGISTER_INFOS_I386_STRUCT
+
+RegisterContextLinux_i386::RegisterContextLinux_i386(const ArchSpec &target_arch) :
+ RegisterInfoInterface(target_arch)
+{
+}
+
+RegisterContextLinux_i386::~RegisterContextLinux_i386()
+{
+}
+
+size_t
+RegisterContextLinux_i386::GetGPRSize()
+{
+ return sizeof(GPR);
+}
+
+const RegisterInfo *
+RegisterContextLinux_i386::GetRegisterInfo()
+{
+ switch (m_target_arch.GetCore())
+ {
+ case ArchSpec::eCore_x86_32_i386:
+ case ArchSpec::eCore_x86_32_i486:
+ case ArchSpec::eCore_x86_32_i486sx:
+ return g_register_infos_i386;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
+ }
+}
diff --git a/source/Plugins/Process/POSIX/RegisterContextLinux_i386.h b/source/Plugins/Process/POSIX/RegisterContextLinux_i386.h
new file mode 100644
index 000000000000..81afdbf8b1cf
--- /dev/null
+++ b/source/Plugins/Process/POSIX/RegisterContextLinux_i386.h
@@ -0,0 +1,29 @@
+//===-- 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_
+
+#include "RegisterContextPOSIX.h"
+
+class RegisterContextLinux_i386
+ : public RegisterInfoInterface
+{
+public:
+ RegisterContextLinux_i386(const lldb_private::ArchSpec &target_arch);
+ virtual ~RegisterContextLinux_i386();
+
+ size_t
+ GetGPRSize();
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfo();
+};
+
+#endif
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);
}
diff --git a/source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.h b/source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.h
index 1509ef55b8dc..21c809b5dc33 100644
--- a/source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.h
+++ b/source/Plugins/Process/POSIX/RegisterContextLinux_x86_64.h
@@ -10,23 +10,20 @@
#ifndef liblldb_RegisterContextLinux_x86_64_H_
#define liblldb_RegisterContextLinux_x86_64_H_
-#include "Plugins/Process/POSIX/RegisterContext_x86_64.h"
+#include "RegisterContextPOSIX.h"
-class RegisterContextLinux_x86_64:
- public RegisterContext_x86_64
+class RegisterContextLinux_x86_64
+ : public RegisterInfoInterface
{
public:
- RegisterContextLinux_x86_64(lldb_private::Thread &thread, uint32_t concrete_frame_idx);
+ RegisterContextLinux_x86_64(const lldb_private::ArchSpec &target_arch);
+ virtual ~RegisterContextLinux_x86_64();
size_t
GetGPRSize();
-protected:
- virtual const lldb_private::RegisterInfo *
+ const lldb_private::RegisterInfo *
GetRegisterInfo();
-
- virtual void
- UpdateRegisterInfo();
};
#endif
diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIX.h b/source/Plugins/Process/POSIX/RegisterContextPOSIX.h
index 63ae01e83a90..e48c528403e3 100644
--- a/source/Plugins/Process/POSIX/RegisterContextPOSIX.h
+++ b/source/Plugins/Process/POSIX/RegisterContextPOSIX.h
@@ -13,20 +13,19 @@
// C Includes
// C++ Includes
// Other libraries and framework includes
+#include "lldb/Core/ArchSpec.h"
#include "lldb/Target/RegisterContext.h"
//------------------------------------------------------------------------------
-/// @class RegisterContextPOSIX
+/// @class POSIXBreakpointProtocol
///
/// @brief Extends RegisterClass with a few virtual operations useful on POSIX.
-class RegisterContextPOSIX
- : public lldb_private::RegisterContext
+class POSIXBreakpointProtocol
{
public:
- RegisterContextPOSIX(lldb_private::Thread &thread,
- uint32_t concrete_frame_idx)
- : RegisterContext(thread, concrete_frame_idx)
+ POSIXBreakpointProtocol()
{ m_watchpoints_initialized = false; }
+ virtual ~POSIXBreakpointProtocol() {}
/// Updates the register state of the associated thread after hitting a
/// breakpoint (if that make sense for the architecture). Default
@@ -35,36 +34,61 @@ public:
///
/// @return
/// True if the operation succeeded and false otherwise.
- virtual bool UpdateAfterBreakpoint() { return true; }
+ virtual bool UpdateAfterBreakpoint() = 0;
/// Determines the index in lldb's register file given a kernel byte offset.
virtual unsigned
- GetRegisterIndexFromOffset(unsigned offset) { return LLDB_INVALID_REGNUM; }
+ GetRegisterIndexFromOffset(unsigned offset) = 0;
// Checks to see if a watchpoint specified by hw_index caused the inferior
// to stop.
virtual bool
- IsWatchpointHit (uint32_t hw_index) { return false; }
+ IsWatchpointHit (uint32_t hw_index) = 0;
// Resets any watchpoints that have been hit.
virtual bool
- ClearWatchpointHits () { return false; }
+ ClearWatchpointHits () = 0;
// Returns the watchpoint address associated with a watchpoint hardware
// index.
virtual lldb::addr_t
- GetWatchpointAddress (uint32_t hw_index) { return LLDB_INVALID_ADDRESS; }
+ GetWatchpointAddress (uint32_t hw_index) = 0;
virtual bool
- IsWatchpointVacant (uint32_t hw_index) { return false; }
+ IsWatchpointVacant (uint32_t hw_index) = 0;
virtual bool
SetHardwareWatchpointWithIndex (lldb::addr_t addr, size_t size,
bool read, bool write,
- uint32_t hw_index) { return false; }
+ uint32_t hw_index) = 0;
+
+ // From lldb_private::RegisterContext
+ virtual uint32_t
+ NumSupportedHardwareWatchpoints () = 0;
protected:
bool m_watchpoints_initialized;
};
+//------------------------------------------------------------------------------
+/// @class RegisterInfoInterface
+///
+/// @brief RegisterInfo interface to patch RegisterInfo structure for archs.
+class RegisterInfoInterface
+{
+public:
+ RegisterInfoInterface(const lldb_private::ArchSpec& target_arch) : m_target_arch(target_arch) {}
+ virtual ~RegisterInfoInterface () {}
+
+ virtual size_t
+ GetGPRSize () = 0;
+
+ virtual const lldb_private::RegisterInfo *
+ GetRegisterInfo () = 0;
+
+public:
+ lldb_private::ArchSpec m_target_arch;
+};
+
#endif // #ifndef liblldb_RegisterContextPOSIX_H_
+
diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.cpp b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.cpp
new file mode 100644
index 000000000000..f70d00e98a3e
--- /dev/null
+++ b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.cpp
@@ -0,0 +1,318 @@
+//===-- RegisterContextPOSIXProcessMonitor_mips64.h ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+
+#include "lldb/Target/Thread.h"
+#include "lldb/Core/RegisterValue.h"
+
+#include "RegisterContextPOSIX_mips64.h"
+#include "ProcessPOSIX.h"
+#include "RegisterContextPOSIXProcessMonitor_mips64.h"
+#include "ProcessMonitor.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+#define REG_CONTEXT_SIZE (GetGPRSize())
+
+RegisterContextPOSIXProcessMonitor_mips64::RegisterContextPOSIXProcessMonitor_mips64(Thread &thread,
+ uint32_t concrete_frame_idx,
+ RegisterInfoInterface *register_info)
+ : RegisterContextPOSIX_mips64(thread, concrete_frame_idx, register_info)
+{
+}
+
+ProcessMonitor &
+RegisterContextPOSIXProcessMonitor_mips64::GetMonitor()
+{
+ ProcessSP base = CalculateProcess();
+ ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get());
+ return process->GetMonitor();
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_mips64::ReadGPR()
+{
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize());
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_mips64::ReadFPR()
+{
+ // XXX not yet implemented
+ return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_mips64::WriteGPR()
+{
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteGPR(m_thread.GetID(), &m_gpr_mips64, GetGPRSize());
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_mips64::WriteFPR()
+{
+ // XXX not yet implemented
+ return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_mips64::ReadRegister(const unsigned reg,
+ RegisterValue &value)
+{
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadRegisterValue(m_thread.GetID(),
+ GetRegisterOffset(reg),
+ GetRegisterName(reg),
+ GetRegisterSize(reg),
+ value);
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_mips64::WriteRegister(const unsigned reg,
+ const RegisterValue &value)
+{
+ unsigned reg_to_write = reg;
+ RegisterValue value_to_write = value;
+
+ // Check if this is a subregister of a full register.
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+ if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
+ {
+ RegisterValue full_value;
+ uint32_t full_reg = reg_info->invalidate_regs[0];
+ const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
+
+ // Read the full register.
+ if (ReadRegister(full_reg_info, full_value))
+ {
+ Error error;
+ ByteOrder byte_order = GetByteOrder();
+ uint8_t dst[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the full register.
+ const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
+ dst,
+ sizeof(dst),
+ byte_order,
+ error);
+ if (error.Success() && dest_size)
+ {
+ uint8_t src[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the source data.
+ const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
+ if (error.Success() && src_size && (src_size < dest_size))
+ {
+ // Copy the src bytes to the destination.
+ memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
+ // Set this full register as the value to write.
+ value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
+ value_to_write.SetType(full_reg_info);
+ reg_to_write = full_reg;
+ }
+ }
+ }
+ }
+
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteRegisterValue(m_thread.GetID(),
+ GetRegisterOffset(reg_to_write),
+ GetRegisterName(reg_to_write),
+ value_to_write);
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_mips64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
+{
+ if (!reg_info)
+ return false;
+
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+ if (IsFPR(reg))
+ {
+ if (!ReadFPR())
+ return false;
+ }
+ else
+ {
+ uint32_t full_reg = reg;
+ bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
+
+ if (is_subreg)
+ {
+ // Read the full aligned 64-bit register.
+ full_reg = reg_info->invalidate_regs[0];
+ }
+
+ bool success = ReadRegister(full_reg, value);
+
+ if (success)
+ {
+ // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right.
+ if (is_subreg && (reg_info->byte_offset & 0x1))
+ value.SetUInt64(value.GetAsUInt64() >> 8);
+
+ // If our return byte size was greater than the return value reg size, then
+ // use the type specified by reg_info rather than the uint64_t default
+ if (value.GetByteSize() > reg_info->byte_size)
+ value.SetType(reg_info);
+ }
+ return success;
+ }
+
+ return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_mips64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
+{
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+ if (IsGPR(reg))
+ return WriteRegister(reg, value);
+
+ return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_mips64::ReadAllRegisterValues(DataBufferSP &data_sp)
+{
+ bool success = false;
+ data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR () && ReadFPR ())
+ {
+ uint8_t *dst = data_sp->GetBytes();
+ success = dst != 0;
+
+ if (success)
+ {
+ ::memcpy (dst, &m_gpr_mips64, GetGPRSize());
+ dst += GetGPRSize();
+ }
+ }
+ return success;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_mips64::WriteAllRegisterValues(const DataBufferSP &data_sp)
+{
+ bool success = false;
+ if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
+ {
+ uint8_t *src = data_sp->GetBytes();
+ if (src)
+ {
+ ::memcpy (&m_gpr_mips64, src, GetGPRSize());
+
+ if (WriteGPR())
+ {
+ src += GetGPRSize();
+ }
+ }
+ }
+ return success;
+}
+
+uint32_t
+RegisterContextPOSIXProcessMonitor_mips64::SetHardwareWatchpoint(addr_t addr, size_t size,
+ bool read, bool write)
+{
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ uint32_t hw_index;
+
+ for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index)
+ {
+ if (IsWatchpointVacant(hw_index))
+ return SetHardwareWatchpointWithIndex(addr, size,
+ read, write,
+ hw_index);
+ }
+
+ return LLDB_INVALID_INDEX32;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_mips64::ClearHardwareWatchpoint(uint32_t hw_index)
+{
+ return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_mips64::HardwareSingleStep(bool enable)
+{
+ return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_mips64::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;
+}
+
+unsigned
+RegisterContextPOSIXProcessMonitor_mips64::GetRegisterIndexFromOffset(unsigned offset)
+{
+ unsigned reg;
+ for (reg = 0; reg < k_num_registers_mips64; reg++)
+ {
+ if (GetRegisterInfo()[reg].byte_offset == offset)
+ break;
+ }
+ assert(reg < k_num_registers_mips64 && "Invalid register offset.");
+ return reg;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_mips64::IsWatchpointHit(uint32_t hw_index)
+{
+ return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_mips64::ClearWatchpointHits()
+{
+ return false;
+}
+
+addr_t
+RegisterContextPOSIXProcessMonitor_mips64::GetWatchpointAddress(uint32_t hw_index)
+{
+ return LLDB_INVALID_ADDRESS;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_mips64::IsWatchpointVacant(uint32_t hw_index)
+{
+ return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_mips64::SetHardwareWatchpointWithIndex(addr_t addr, size_t size,
+ bool read, bool write,
+ uint32_t hw_index)
+{
+ return false;
+}
+
+uint32_t
+RegisterContextPOSIXProcessMonitor_mips64::NumSupportedHardwareWatchpoints()
+{
+ return 0;
+}
+
diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.h b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.h
new file mode 100644
index 000000000000..8f545eef0d5e
--- /dev/null
+++ b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_mips64.h
@@ -0,0 +1,95 @@
+//===-- RegisterContextPOSIXProcessMonitor_mips64.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_RegisterContextPOSIXProcessMonitor_mips64_H_
+#define liblldb_RegisterContextPOSIXProcessMonitor_mips64_H_
+
+#include "Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h"
+
+class RegisterContextPOSIXProcessMonitor_mips64:
+ public RegisterContextPOSIX_mips64,
+ public POSIXBreakpointProtocol
+{
+public:
+ RegisterContextPOSIXProcessMonitor_mips64(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx,
+ RegisterInfoInterface *register_info);
+
+protected:
+ bool
+ ReadGPR();
+
+ bool
+ ReadFPR();
+
+ bool
+ WriteGPR();
+
+ bool
+ WriteFPR();
+
+ // lldb_private::RegisterContext
+ bool
+ ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
+
+ bool
+ WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value);
+
+ bool
+ ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
+
+ bool
+ WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
+
+ bool
+ ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
+
+ bool
+ WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
+
+ uint32_t
+ SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write);
+
+ bool
+ ClearHardwareWatchpoint(uint32_t hw_index);
+
+ bool
+ HardwareSingleStep(bool enable);
+
+ // POSIXBreakpointProtocol
+ bool
+ UpdateAfterBreakpoint();
+
+ unsigned
+ GetRegisterIndexFromOffset(unsigned offset);
+
+ bool
+ IsWatchpointHit(uint32_t hw_index);
+
+ bool
+ ClearWatchpointHits();
+
+ lldb::addr_t
+ GetWatchpointAddress(uint32_t hw_index);
+
+ bool
+ IsWatchpointVacant(uint32_t hw_index);
+
+ bool
+ SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index);
+
+ uint32_t
+ NumSupportedHardwareWatchpoints();
+
+private:
+ ProcessMonitor &
+ GetMonitor();
+};
+
+#endif
diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.cpp b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.cpp
new file mode 100644
index 000000000000..98e0bce68678
--- /dev/null
+++ b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.cpp
@@ -0,0 +1,634 @@
+//===-- RegisterContextPOSIXProcessMonitor_x86.h ---------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+
+#include "lldb/Target/Thread.h"
+#include "lldb/Core/RegisterValue.h"
+
+#include "ProcessPOSIX.h"
+#include "RegisterContextPOSIXProcessMonitor_x86.h"
+#include "ProcessMonitor.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+// Support ptrace extensions even when compiled without required kernel support
+#ifndef NT_X86_XSTATE
+ #define NT_X86_XSTATE 0x202
+#endif
+
+#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof(FPR))
+
+static uint32_t
+size_and_rw_bits(size_t size, bool read, bool write)
+{
+ uint32_t rw;
+
+ if (read)
+ rw = 0x3; // READ or READ/WRITE
+ else if (write)
+ rw = 0x1; // WRITE
+ else
+ assert(0 && "read and write cannot both be false");
+
+ switch (size)
+ {
+ case 1:
+ return rw;
+ case 2:
+ return (0x1 << 2) | rw;
+ case 4:
+ return (0x3 << 2) | rw;
+ case 8:
+ return (0x2 << 2) | rw;
+ default:
+ assert(0 && "invalid size, must be one of 1, 2, 4, or 8");
+ }
+}
+
+RegisterContextPOSIXProcessMonitor_x86_64::RegisterContextPOSIXProcessMonitor_x86_64(Thread &thread,
+ uint32_t concrete_frame_idx,
+ RegisterInfoInterface *register_info)
+ : RegisterContextPOSIX_x86(thread, concrete_frame_idx, register_info)
+{
+}
+
+ProcessMonitor &
+RegisterContextPOSIXProcessMonitor_x86_64::GetMonitor()
+{
+ ProcessSP base = CalculateProcess();
+ ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get());
+ return process->GetMonitor();
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::ReadGPR()
+{
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadGPR(m_thread.GetID(), &m_gpr_x86_64, GetGPRSize());
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::ReadFPR()
+{
+ ProcessMonitor &monitor = GetMonitor();
+ if (GetFPRType() == eFXSAVE)
+ return monitor.ReadFPR(m_thread.GetID(), &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
+
+ if (GetFPRType() == eXSAVE)
+ return monitor.ReadRegisterSet(m_thread.GetID(), &m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
+ return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::WriteGPR()
+{
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteGPR(m_thread.GetID(), &m_gpr_x86_64, GetGPRSize());
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::WriteFPR()
+{
+ ProcessMonitor &monitor = GetMonitor();
+ if (GetFPRType() == eFXSAVE)
+ return monitor.WriteFPR(m_thread.GetID(), &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
+
+ if (GetFPRType() == eXSAVE)
+ return monitor.WriteRegisterSet(m_thread.GetID(), &m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
+ return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(const unsigned reg,
+ RegisterValue &value)
+{
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.ReadRegisterValue(m_thread.GetID(),
+ GetRegisterOffset(reg),
+ GetRegisterName(reg),
+ GetRegisterSize(reg),
+ value);
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(const unsigned reg,
+ const RegisterValue &value)
+{
+ unsigned reg_to_write = reg;
+ RegisterValue value_to_write = value;
+
+ // Check if this is a subregister of a full register.
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg);
+ if (reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM))
+ {
+ RegisterValue full_value;
+ uint32_t full_reg = reg_info->invalidate_regs[0];
+ const RegisterInfo *full_reg_info = GetRegisterInfoAtIndex(full_reg);
+
+ // Read the full register.
+ if (ReadRegister(full_reg_info, full_value))
+ {
+ Error error;
+ ByteOrder byte_order = GetByteOrder();
+ uint8_t dst[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the full register.
+ const uint32_t dest_size = full_value.GetAsMemoryData (full_reg_info,
+ dst,
+ sizeof(dst),
+ byte_order,
+ error);
+ if (error.Success() && dest_size)
+ {
+ uint8_t src[RegisterValue::kMaxRegisterByteSize];
+
+ // Get the bytes for the source data.
+ const uint32_t src_size = value.GetAsMemoryData (reg_info, src, sizeof(src), byte_order, error);
+ if (error.Success() && src_size && (src_size < dest_size))
+ {
+ // Copy the src bytes to the destination.
+ memcpy (dst + (reg_info->byte_offset & 0x1), src, src_size);
+ // Set this full register as the value to write.
+ value_to_write.SetBytes(dst, full_value.GetByteSize(), byte_order);
+ value_to_write.SetType(full_reg_info);
+ reg_to_write = full_reg;
+ }
+ }
+ }
+ }
+
+ ProcessMonitor &monitor = GetMonitor();
+ return monitor.WriteRegisterValue(m_thread.GetID(),
+ GetRegisterOffset(reg_to_write),
+ GetRegisterName(reg_to_write),
+ value_to_write);
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
+{
+ if (!reg_info)
+ return false;
+
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+ if (IsFPR(reg, GetFPRType()))
+ {
+ if (!ReadFPR())
+ return false;
+ }
+ else
+ {
+ uint32_t full_reg = reg;
+ bool is_subreg = reg_info->invalidate_regs && (reg_info->invalidate_regs[0] != LLDB_INVALID_REGNUM);
+
+ if (is_subreg)
+ {
+ // Read the full aligned 64-bit register.
+ full_reg = reg_info->invalidate_regs[0];
+ }
+
+ bool success = ReadRegister(full_reg, value);
+
+ if (success)
+ {
+ // If our read was not aligned (for ah,bh,ch,dh), shift our returned value one byte to the right.
+ if (is_subreg && (reg_info->byte_offset & 0x1))
+ value.SetUInt64(value.GetAsUInt64() >> 8);
+
+ // If our return byte size was greater than the return value reg size, then
+ // use the type specified by reg_info rather than the uint64_t default
+ if (value.GetByteSize() > reg_info->byte_size)
+ value.SetType(reg_info);
+ }
+ return success;
+ }
+
+ if (reg_info->encoding == eEncodingVector)
+ {
+ ByteOrder byte_order = GetByteOrder();
+
+ if (byte_order != ByteOrder::eByteOrderInvalid)
+ {
+ if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
+ value.SetBytes(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes, reg_info->byte_size, byte_order);
+ if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
+ value.SetBytes(m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes, reg_info->byte_size, byte_order);
+ if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
+ value.SetBytes(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes, reg_info->byte_size, byte_order);
+ if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm)
+ {
+ // Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
+ if (GetFPRType() == eXSAVE && CopyXSTATEtoYMM(reg, byte_order))
+ value.SetBytes(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, reg_info->byte_size, byte_order);
+ else
+ return false;
+ }
+ return value.GetType() == RegisterValue::eTypeBytes;
+ }
+ return false;
+ }
+
+ // Get pointer to m_fpr.xstate.fxsave variable and set the data from it.
+ assert (reg_info->byte_offset < sizeof(m_fpr));
+ uint8_t *src = (uint8_t *)&m_fpr + reg_info->byte_offset;
+ switch (reg_info->byte_size)
+ {
+ case 2:
+ value.SetUInt16(*(uint16_t *)src);
+ return true;
+ case 4:
+ value.SetUInt32(*(uint32_t *)src);
+ return true;
+ case 8:
+ value.SetUInt64(*(uint64_t *)src);
+ return true;
+ default:
+ assert(false && "Unhandled data size.");
+ return false;
+ }
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::WriteRegister(const RegisterInfo *reg_info, const RegisterValue &value)
+{
+ const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+
+ if (IsGPR(reg))
+ return WriteRegister(reg, value);
+
+ if (IsFPR(reg, GetFPRType()))
+ {
+ if (reg_info->encoding == eEncodingVector)
+ {
+ if (reg >= m_reg_info.first_st && reg <= m_reg_info.last_st)
+ ::memcpy (m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_st].bytes, value.GetBytes(), value.GetByteSize());
+
+ if (reg >= m_reg_info.first_mm && reg <= m_reg_info.last_mm)
+ ::memcpy (m_fpr.xstate.fxsave.stmm[reg - m_reg_info.first_mm].bytes, value.GetBytes(), value.GetByteSize());
+
+ if (reg >= m_reg_info.first_xmm && reg <= m_reg_info.last_xmm)
+ ::memcpy (m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_xmm].bytes, value.GetBytes(), value.GetByteSize());
+
+ if (reg >= m_reg_info.first_ymm && reg <= m_reg_info.last_ymm)
+ {
+ if (GetFPRType() != eXSAVE)
+ return false; // the target processor does not support AVX
+
+ // Store ymm register content, and split into the register halves in xmm.bytes and ymmh.bytes
+ ::memcpy (m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes, value.GetBytes(), value.GetByteSize());
+ if (false == CopyYMMtoXSTATE(reg, GetByteOrder()))
+ return false;
+ }
+ }
+ else
+ {
+ // Get pointer to m_fpr.xstate.fxsave variable and set the data to it.
+ assert (reg_info->byte_offset < sizeof(m_fpr));
+ uint8_t *dst = (uint8_t *)&m_fpr + reg_info->byte_offset;
+ switch (reg_info->byte_size)
+ {
+ case 2:
+ *(uint16_t *)dst = value.GetAsUInt16();
+ break;
+ case 4:
+ *(uint32_t *)dst = value.GetAsUInt32();
+ break;
+ case 8:
+ *(uint64_t *)dst = value.GetAsUInt64();
+ break;
+ default:
+ assert(false && "Unhandled data size.");
+ return false;
+ }
+ }
+
+ if (WriteFPR())
+ {
+ if (IsAVX(reg))
+ return CopyYMMtoXSTATE(reg, GetByteOrder());
+ return true;
+ }
+ }
+ return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::ReadAllRegisterValues(DataBufferSP &data_sp)
+{
+ bool success = false;
+ data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
+ if (data_sp && ReadGPR () && ReadFPR ())
+ {
+ uint8_t *dst = data_sp->GetBytes();
+ success = dst != 0;
+
+ if (success)
+ {
+ ::memcpy (dst, &m_gpr_x86_64, GetGPRSize());
+ dst += GetGPRSize();
+ }
+ if (GetFPRType() == eFXSAVE)
+ ::memcpy (dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
+
+ if (GetFPRType() == eXSAVE)
+ {
+ ByteOrder byte_order = GetByteOrder();
+
+ // Assemble the YMM register content from the register halves.
+ for (uint32_t reg = m_reg_info.first_ymm; success && reg <= m_reg_info.last_ymm; ++reg)
+ success = CopyXSTATEtoYMM(reg, byte_order);
+
+ if (success)
+ {
+ // Copy the extended register state including the assembled ymm registers.
+ ::memcpy (dst, &m_fpr, sizeof(m_fpr));
+ }
+ }
+ }
+ return success;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::WriteAllRegisterValues(const DataBufferSP &data_sp)
+{
+ bool success = false;
+ if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
+ {
+ uint8_t *src = data_sp->GetBytes();
+ if (src)
+ {
+ ::memcpy (&m_gpr_x86_64, src, GetGPRSize());
+
+ if (WriteGPR())
+ {
+ src += GetGPRSize();
+ if (GetFPRType() == eFXSAVE)
+ ::memcpy (&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
+ if (GetFPRType() == eXSAVE)
+ ::memcpy (&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
+
+ success = WriteFPR();
+ if (success)
+ {
+ success = true;
+
+ if (GetFPRType() == eXSAVE)
+ {
+ ByteOrder byte_order = GetByteOrder();
+
+ // Parse the YMM register content from the register halves.
+ for (uint32_t reg = m_reg_info.first_ymm; success && reg <= m_reg_info.last_ymm; ++reg)
+ success = CopyYMMtoXSTATE(reg, byte_order);
+ }
+ }
+ }
+ }
+ }
+ return success;
+}
+
+uint32_t
+RegisterContextPOSIXProcessMonitor_x86_64::SetHardwareWatchpoint(addr_t addr, size_t size,
+ bool read, bool write)
+{
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+ uint32_t hw_index;
+
+ for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index)
+ {
+ if (IsWatchpointVacant(hw_index))
+ return SetHardwareWatchpointWithIndex(addr, size,
+ read, write,
+ hw_index);
+ }
+
+ return LLDB_INVALID_INDEX32;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::ClearHardwareWatchpoint(uint32_t hw_index)
+{
+ if (hw_index < NumSupportedHardwareWatchpoints())
+ {
+ RegisterValue current_dr7_bits;
+
+ if (ReadRegister(m_reg_info.first_dr + 7, current_dr7_bits))
+ {
+ uint64_t new_dr7_bits = current_dr7_bits.GetAsUInt64() & ~(3 << (2*hw_index));
+
+ if (WriteRegister(m_reg_info.first_dr + 7, RegisterValue(new_dr7_bits)))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::HardwareSingleStep(bool enable)
+{
+ enum { TRACE_BIT = 0x100 };
+ uint64_t rflags;
+
+ if ((rflags = ReadRegisterAsUnsigned(m_reg_info.gpr_flags, -1UL)) == -1UL)
+ return false;
+
+ if (enable)
+ {
+ if (rflags & TRACE_BIT)
+ return true;
+
+ rflags |= TRACE_BIT;
+ }
+ else
+ {
+ if (!(rflags & TRACE_BIT))
+ return false;
+
+ rflags &= ~TRACE_BIT;
+ }
+
+ return WriteRegisterFromUnsigned(m_reg_info.gpr_flags, rflags);
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::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;
+}
+
+unsigned
+RegisterContextPOSIXProcessMonitor_x86_64::GetRegisterIndexFromOffset(unsigned offset)
+{
+ unsigned reg;
+ for (reg = 0; reg < m_reg_info.num_registers; reg++)
+ {
+ if (GetRegisterInfo()[reg].byte_offset == offset)
+ break;
+ }
+ assert(reg < m_reg_info.num_registers && "Invalid register offset.");
+ return reg;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointHit(uint32_t hw_index)
+{
+ bool is_hit = false;
+
+ if (m_watchpoints_initialized == false)
+ {
+ // Reset the debug status and debug control registers
+ RegisterValue zero_bits = RegisterValue(uint64_t(0));
+ if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) || !WriteRegister(m_reg_info.first_dr + 7, zero_bits))
+ assert(false && "Could not initialize watchpoint registers");
+ m_watchpoints_initialized = true;
+ }
+
+ if (hw_index < NumSupportedHardwareWatchpoints())
+ {
+ RegisterValue value;
+
+ if (ReadRegister(m_reg_info.first_dr + 6, value))
+ {
+ uint64_t val = value.GetAsUInt64();
+ is_hit = val & (1 << hw_index);
+ }
+ }
+
+ return is_hit;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::ClearWatchpointHits()
+{
+ return WriteRegister(m_reg_info.first_dr + 6, RegisterValue((uint64_t)0));
+}
+
+addr_t
+RegisterContextPOSIXProcessMonitor_x86_64::GetWatchpointAddress(uint32_t hw_index)
+{
+ addr_t wp_monitor_addr = LLDB_INVALID_ADDRESS;
+
+ if (hw_index < NumSupportedHardwareWatchpoints())
+ {
+ if (!IsWatchpointVacant(hw_index))
+ {
+ RegisterValue value;
+
+ if (ReadRegister(m_reg_info.first_dr + hw_index, value))
+ wp_monitor_addr = value.GetAsUInt64();
+ }
+ }
+
+ return wp_monitor_addr;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::IsWatchpointVacant(uint32_t hw_index)
+{
+ bool is_vacant = false;
+ RegisterValue value;
+
+ assert(hw_index < NumSupportedHardwareWatchpoints());
+
+ if (m_watchpoints_initialized == false)
+ {
+ // Reset the debug status and debug control registers
+ RegisterValue zero_bits = RegisterValue(uint64_t(0));
+ if (!WriteRegister(m_reg_info.first_dr + 6, zero_bits) || !WriteRegister(m_reg_info.first_dr + 7, zero_bits))
+ assert(false && "Could not initialize watchpoint registers");
+ m_watchpoints_initialized = true;
+ }
+
+ if (ReadRegister(m_reg_info.first_dr + 7, value))
+ {
+ uint64_t val = value.GetAsUInt64();
+ is_vacant = (val & (3 << 2*hw_index)) == 0;
+ }
+
+ return is_vacant;
+}
+
+bool
+RegisterContextPOSIXProcessMonitor_x86_64::SetHardwareWatchpointWithIndex(addr_t addr, size_t size,
+ bool read, bool write,
+ uint32_t hw_index)
+{
+ const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
+
+ if (num_hw_watchpoints == 0 || hw_index >= num_hw_watchpoints)
+ return false;
+
+ if (!(size == 1 || size == 2 || size == 4 || size == 8))
+ return false;
+
+ if (read == false && write == false)
+ return false;
+
+ if (!IsWatchpointVacant(hw_index))
+ return false;
+
+ // Set both dr7 (debug control register) and dri (debug address register).
+
+ // dr7{7-0} encodes the local/global enable bits:
+ // global enable --. .-- local enable
+ // | |
+ // v v
+ // dr0 -> bits{1-0}
+ // dr1 -> bits{3-2}
+ // dr2 -> bits{5-4}
+ // dr3 -> bits{7-6}
+ //
+ // dr7{31-16} encodes the rw/len bits:
+ // b_x+3, b_x+2, b_x+1, b_x
+ // where bits{x+1, x} => rw
+ // 0b00: execute, 0b01: write, 0b11: read-or-write,
+ // 0b10: io read-or-write (unused)
+ // and bits{x+3, x+2} => len
+ // 0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte
+ //
+ // dr0 -> bits{19-16}
+ // dr1 -> bits{23-20}
+ // dr2 -> bits{27-24}
+ // dr3 -> bits{31-28}
+ if (hw_index < num_hw_watchpoints)
+ {
+ RegisterValue current_dr7_bits;
+
+ if (ReadRegister(m_reg_info.first_dr + 7, current_dr7_bits))
+ {
+ uint64_t new_dr7_bits = current_dr7_bits.GetAsUInt64() |
+ (1 << (2*hw_index) |
+ size_and_rw_bits(size, read, write) <<
+ (16+4*hw_index));
+
+ if (WriteRegister(m_reg_info.first_dr + hw_index, RegisterValue(addr)) &&
+ WriteRegister(m_reg_info.first_dr + 7, RegisterValue(new_dr7_bits)))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+uint32_t
+RegisterContextPOSIXProcessMonitor_x86_64::NumSupportedHardwareWatchpoints()
+{
+ // Available debug address registers: dr0, dr1, dr2, dr3
+ return 4;
+}
+
diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.h b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.h
new file mode 100644
index 000000000000..2b64fa8003a2
--- /dev/null
+++ b/source/Plugins/Process/POSIX/RegisterContextPOSIXProcessMonitor_x86.h
@@ -0,0 +1,95 @@
+//===-- RegisterContextPOSIXProcessMonitor_x86.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_RegisterContextPOSIXProcessMonitor_x86_H_
+#define liblldb_RegisterContextPOSIXProcessMonitor_x86_H_
+
+#include "Plugins/Process/POSIX/RegisterContextPOSIX_x86.h"
+
+class RegisterContextPOSIXProcessMonitor_x86_64:
+ public RegisterContextPOSIX_x86,
+ public POSIXBreakpointProtocol
+{
+public:
+ RegisterContextPOSIXProcessMonitor_x86_64(lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx,
+ RegisterInfoInterface *register_info);
+
+protected:
+ bool
+ ReadGPR();
+
+ bool
+ ReadFPR();
+
+ bool
+ WriteGPR();
+
+ bool
+ WriteFPR();
+
+ // lldb_private::RegisterContext
+ bool
+ ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
+
+ bool
+ WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value);
+
+ bool
+ ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
+
+ bool
+ WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
+
+ bool
+ ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
+
+ bool
+ WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
+
+ uint32_t
+ SetHardwareWatchpoint(lldb::addr_t addr, size_t size, bool read, bool write);
+
+ bool
+ ClearHardwareWatchpoint(uint32_t hw_index);
+
+ bool
+ HardwareSingleStep(bool enable);
+
+ // POSIXBreakpointProtocol
+ bool
+ UpdateAfterBreakpoint();
+
+ unsigned
+ GetRegisterIndexFromOffset(unsigned offset);
+
+ bool
+ IsWatchpointHit(uint32_t hw_index);
+
+ bool
+ ClearWatchpointHits();
+
+ lldb::addr_t
+ GetWatchpointAddress(uint32_t hw_index);
+
+ bool
+ IsWatchpointVacant(uint32_t hw_index);
+
+ bool
+ SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size, bool read, bool write, uint32_t hw_index);
+
+ uint32_t
+ NumSupportedHardwareWatchpoints();
+
+private:
+ ProcessMonitor &
+ GetMonitor();
+};
+
+#endif
diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.cpp b/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.cpp
new file mode 100644
index 000000000000..45c99aec1657
--- /dev/null
+++ b/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.cpp
@@ -0,0 +1,238 @@
+//===-- RegisterContextPOSIX_mips64.cpp -------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <cstring>
+#include <errno.h>
+#include <stdint.h>
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Core/Scalar.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Host/Endian.h"
+#include "llvm/Support/Compiler.h"
+
+#include "ProcessPOSIX.h"
+#include "RegisterContextPOSIX_mips64.h"
+#include "Plugins/Process/elf-core/ProcessElfCore.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+static const
+uint32_t g_gpr_regnums[] =
+{
+ gpr_zero_mips64,
+ gpr_r1_mips64,
+ gpr_r2_mips64,
+ gpr_r3_mips64,
+ gpr_r4_mips64,
+ gpr_r5_mips64,
+ gpr_r6_mips64,
+ gpr_r7_mips64,
+ gpr_r8_mips64,
+ gpr_r9_mips64,
+ gpr_r10_mips64,
+ gpr_r11_mips64,
+ gpr_r12_mips64,
+ gpr_r13_mips64,
+ gpr_r14_mips64,
+ gpr_r15_mips64,
+ gpr_r16_mips64,
+ gpr_r17_mips64,
+ gpr_r18_mips64,
+ gpr_r19_mips64,
+ gpr_r20_mips64,
+ gpr_r21_mips64,
+ gpr_r22_mips64,
+ gpr_r23_mips64,
+ gpr_r24_mips64,
+ gpr_r25_mips64,
+ gpr_r26_mips64,
+ gpr_r27_mips64,
+ gpr_gp_mips64,
+ gpr_sp_mips64,
+ gpr_r30_mips64,
+ gpr_ra_mips64,
+ gpr_sr_mips64,
+ gpr_mullo_mips64,
+ gpr_mulhi_mips64,
+ gpr_badvaddr_mips64,
+ gpr_cause_mips64,
+ gpr_pc_mips64,
+ gpr_ic_mips64,
+ gpr_dummy_mips64
+};
+
+// Number of register sets provided by this context.
+enum
+{
+ k_num_register_sets = 1
+};
+
+static const RegisterSet
+g_reg_sets_mips64[k_num_register_sets] =
+{
+ { "General Purpose Registers", "gpr", k_num_gpr_registers_mips64, g_gpr_regnums },
+};
+
+bool RegisterContextPOSIX_mips64::IsGPR(unsigned reg)
+{
+ return reg <= k_num_gpr_registers_mips64; // GPR's come first.
+}
+
+bool
+RegisterContextPOSIX_mips64::IsFPR(unsigned reg)
+{
+ // XXX
+ return false;
+}
+
+RegisterContextPOSIX_mips64::RegisterContextPOSIX_mips64(Thread &thread,
+ uint32_t concrete_frame_idx,
+ RegisterInfoInterface *register_info)
+ : RegisterContext(thread, concrete_frame_idx)
+{
+ m_register_info_ap.reset(register_info);
+
+ // elf-core yet to support ReadFPR()
+ ProcessSP base = CalculateProcess();
+ if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
+ return;
+}
+
+RegisterContextPOSIX_mips64::~RegisterContextPOSIX_mips64()
+{
+}
+
+void
+RegisterContextPOSIX_mips64::Invalidate()
+{
+}
+
+void
+RegisterContextPOSIX_mips64::InvalidateAllRegisters()
+{
+}
+
+unsigned
+RegisterContextPOSIX_mips64::GetRegisterOffset(unsigned reg)
+{
+ assert(reg < k_num_registers_mips64 && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_offset;
+}
+
+unsigned
+RegisterContextPOSIX_mips64::GetRegisterSize(unsigned reg)
+{
+ assert(reg < k_num_registers_mips64 && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_size;
+}
+
+size_t
+RegisterContextPOSIX_mips64::GetRegisterCount()
+{
+ size_t num_registers = k_num_registers_mips64;
+ return num_registers;
+}
+
+size_t
+RegisterContextPOSIX_mips64::GetGPRSize()
+{
+ return m_register_info_ap->GetGPRSize();
+}
+
+const RegisterInfo *
+RegisterContextPOSIX_mips64::GetRegisterInfo()
+{
+ // Commonly, this method is overridden and g_register_infos is copied and specialized.
+ // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+ return m_register_info_ap->GetRegisterInfo ();
+}
+
+const RegisterInfo *
+RegisterContextPOSIX_mips64::GetRegisterInfoAtIndex(size_t reg)
+{
+ if (reg < k_num_registers_mips64)
+ return &GetRegisterInfo()[reg];
+ else
+ return NULL;
+}
+
+size_t
+RegisterContextPOSIX_mips64::GetRegisterSetCount()
+{
+ size_t sets = 0;
+ for (size_t set = 0; set < k_num_register_sets; ++set)
+ {
+ if (IsRegisterSetAvailable(set))
+ ++sets;
+ }
+
+ return sets;
+}
+
+const RegisterSet *
+RegisterContextPOSIX_mips64::GetRegisterSet(size_t set)
+{
+ if (IsRegisterSetAvailable(set))
+ return &g_reg_sets_mips64[set];
+ else
+ return NULL;
+}
+
+const char *
+RegisterContextPOSIX_mips64::GetRegisterName(unsigned reg)
+{
+ assert(reg < k_num_registers_mips64 && "Invalid register offset.");
+ return GetRegisterInfo()[reg].name;
+}
+
+lldb::ByteOrder
+RegisterContextPOSIX_mips64::GetByteOrder()
+{
+ // Get the target process whose privileged thread was used for the register read.
+ lldb::ByteOrder byte_order = eByteOrderInvalid;
+ Process *process = CalculateProcess().get();
+
+ if (process)
+ byte_order = process->GetByteOrder();
+ return byte_order;
+}
+
+bool
+RegisterContextPOSIX_mips64::IsRegisterSetAvailable(size_t set_index)
+{
+ size_t num_sets = k_num_register_sets;
+
+ return (set_index < num_sets);
+}
+
+// Used when parsing DWARF and EH frame information and any other
+// object file sections that contain register numbers in them.
+uint32_t
+RegisterContextPOSIX_mips64::ConvertRegisterKindToRegisterNumber(uint32_t kind,
+ uint32_t num)
+{
+ const uint32_t num_regs = GetRegisterCount();
+
+ assert (kind < kNumRegisterKinds);
+ for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
+ {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
+
+ if (reg_info->kinds[kind] == num)
+ return reg_idx;
+ }
+
+ return LLDB_INVALID_REGNUM;
+}
+
diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h b/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h
new file mode 100644
index 000000000000..a2a7d1f45271
--- /dev/null
+++ b/source/Plugins/Process/POSIX/RegisterContextPOSIX_mips64.h
@@ -0,0 +1,138 @@
+//===-- RegisterContextPOSIX_mips64.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_RegisterContextPOSIX_mips64_H_
+#define liblldb_RegisterContextPOSIX_mips64_H_
+
+#include "lldb/Core/Log.h"
+#include "RegisterContextPOSIX.h"
+#include "RegisterContext_mips64.h"
+
+class ProcessMonitor;
+
+// ---------------------------------------------------------------------------
+// Internal codes for all mips64 registers.
+// ---------------------------------------------------------------------------
+enum
+{
+ k_first_gpr_mips64,
+ gpr_zero_mips64 = k_first_gpr_mips64,
+ gpr_r1_mips64,
+ gpr_r2_mips64,
+ gpr_r3_mips64,
+ gpr_r4_mips64,
+ gpr_r5_mips64,
+ gpr_r6_mips64,
+ gpr_r7_mips64,
+ gpr_r8_mips64,
+ gpr_r9_mips64,
+ gpr_r10_mips64,
+ gpr_r11_mips64,
+ gpr_r12_mips64,
+ gpr_r13_mips64,
+ gpr_r14_mips64,
+ gpr_r15_mips64,
+ gpr_r16_mips64,
+ gpr_r17_mips64,
+ gpr_r18_mips64,
+ gpr_r19_mips64,
+ gpr_r20_mips64,
+ gpr_r21_mips64,
+ gpr_r22_mips64,
+ gpr_r23_mips64,
+ gpr_r24_mips64,
+ gpr_r25_mips64,
+ gpr_r26_mips64,
+ gpr_r27_mips64,
+ gpr_gp_mips64,
+ gpr_sp_mips64,
+ gpr_r30_mips64,
+ gpr_ra_mips64,
+ gpr_sr_mips64,
+ gpr_mullo_mips64,
+ gpr_mulhi_mips64,
+ gpr_badvaddr_mips64,
+ gpr_cause_mips64,
+ gpr_pc_mips64,
+ gpr_ic_mips64,
+ gpr_dummy_mips64,
+
+ k_num_registers_mips64,
+ k_num_gpr_registers_mips64 = k_num_registers_mips64
+};
+
+class RegisterContextPOSIX_mips64
+ : public lldb_private::RegisterContext
+{
+public:
+ RegisterContextPOSIX_mips64 (lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx,
+ RegisterInfoInterface *register_info);
+
+ ~RegisterContextPOSIX_mips64();
+
+ void
+ Invalidate();
+
+ void
+ InvalidateAllRegisters();
+
+ size_t
+ GetRegisterCount();
+
+ virtual size_t
+ GetGPRSize();
+
+ virtual unsigned
+ GetRegisterSize(unsigned reg);
+
+ virtual unsigned
+ GetRegisterOffset(unsigned reg);
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoAtIndex(size_t reg);
+
+ size_t
+ GetRegisterSetCount();
+
+ const lldb_private::RegisterSet *
+ GetRegisterSet(size_t set);
+
+ const char *
+ GetRegisterName(unsigned reg);
+
+ uint32_t
+ ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num);
+
+protected:
+ uint64_t m_gpr_mips64[k_num_gpr_registers_mips64]; // general purpose registers.
+ std::unique_ptr<RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
+
+ // Determines if an extended register set is supported on the processor running the inferior process.
+ virtual bool
+ IsRegisterSetAvailable(size_t set_index);
+
+ virtual const lldb_private::RegisterInfo *
+ GetRegisterInfo();
+
+ bool
+ IsGPR(unsigned reg);
+
+ bool
+ IsFPR(unsigned reg);
+
+ lldb::ByteOrder GetByteOrder();
+
+ virtual bool ReadGPR() = 0;
+ virtual bool ReadFPR() = 0;
+ virtual bool WriteGPR() = 0;
+ virtual bool WriteFPR() = 0;
+};
+
+#endif // #ifndef liblldb_RegisterContextPOSIX_mips64_H_
diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIX_x86.cpp b/source/Plugins/Process/POSIX/RegisterContextPOSIX_x86.cpp
new file mode 100644
index 000000000000..9ae541a6309b
--- /dev/null
+++ b/source/Plugins/Process/POSIX/RegisterContextPOSIX_x86.cpp
@@ -0,0 +1,666 @@
+//===-- RegisterContextPOSIX_x86.cpp ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <cstring>
+#include <errno.h>
+#include <stdint.h>
+
+#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/RegisterValue.h"
+#include "lldb/Core/Scalar.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Host/Endian.h"
+#include "llvm/Support/Compiler.h"
+
+#include "ProcessPOSIX.h"
+#include "RegisterContext_x86.h"
+#include "RegisterContextPOSIX_x86.h"
+#include "Plugins/Process/elf-core/ProcessElfCore.h"
+
+using namespace lldb_private;
+using namespace lldb;
+
+const uint32_t
+g_gpr_regnums_i386[] =
+{
+ gpr_eax_i386,
+ gpr_ebx_i386,
+ gpr_ecx_i386,
+ gpr_edx_i386,
+ gpr_edi_i386,
+ gpr_esi_i386,
+ gpr_ebp_i386,
+ gpr_esp_i386,
+ gpr_eip_i386,
+ gpr_eflags_i386,
+ gpr_cs_i386,
+ gpr_fs_i386,
+ gpr_gs_i386,
+ gpr_ss_i386,
+ gpr_ds_i386,
+ gpr_es_i386,
+ gpr_ax_i386,
+ gpr_bx_i386,
+ gpr_cx_i386,
+ gpr_dx_i386,
+ gpr_di_i386,
+ gpr_si_i386,
+ gpr_bp_i386,
+ gpr_sp_i386,
+ gpr_ah_i386,
+ gpr_bh_i386,
+ gpr_ch_i386,
+ gpr_dh_i386,
+ gpr_al_i386,
+ gpr_bl_i386,
+ gpr_cl_i386,
+ gpr_dl_i386
+};
+static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) == k_num_gpr_registers_i386,
+ "g_gpr_regnums_i386 has wrong number of register infos");
+
+const uint32_t
+g_fpu_regnums_i386[] =
+{
+ fpu_fctrl_i386,
+ fpu_fstat_i386,
+ fpu_ftag_i386,
+ fpu_fop_i386,
+ fpu_fiseg_i386,
+ fpu_fioff_i386,
+ fpu_foseg_i386,
+ fpu_fooff_i386,
+ fpu_mxcsr_i386,
+ fpu_mxcsrmask_i386,
+ fpu_st0_i386,
+ fpu_st1_i386,
+ fpu_st2_i386,
+ fpu_st3_i386,
+ fpu_st4_i386,
+ fpu_st5_i386,
+ fpu_st6_i386,
+ fpu_st7_i386,
+ fpu_mm0_i386,
+ fpu_mm1_i386,
+ fpu_mm2_i386,
+ fpu_mm3_i386,
+ fpu_mm4_i386,
+ fpu_mm5_i386,
+ fpu_mm6_i386,
+ fpu_mm7_i386,
+ fpu_xmm0_i386,
+ fpu_xmm1_i386,
+ fpu_xmm2_i386,
+ fpu_xmm3_i386,
+ fpu_xmm4_i386,
+ fpu_xmm5_i386,
+ fpu_xmm6_i386,
+ fpu_xmm7_i386
+};
+static_assert((sizeof(g_fpu_regnums_i386) / sizeof(g_fpu_regnums_i386[0])) == k_num_fpr_registers_i386,
+ "g_fpu_regnums_i386 has wrong number of register infos");
+
+const uint32_t
+g_avx_regnums_i386[] =
+{
+ fpu_ymm0_i386,
+ fpu_ymm1_i386,
+ fpu_ymm2_i386,
+ fpu_ymm3_i386,
+ fpu_ymm4_i386,
+ fpu_ymm5_i386,
+ fpu_ymm6_i386,
+ fpu_ymm7_i386
+};
+static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) == k_num_avx_registers_i386,
+ " g_avx_regnums_i386 has wrong number of register infos");
+
+static const
+uint32_t g_gpr_regnums_x86_64[] =
+{
+ gpr_rax_x86_64,
+ gpr_rbx_x86_64,
+ gpr_rcx_x86_64,
+ gpr_rdx_x86_64,
+ gpr_rdi_x86_64,
+ gpr_rsi_x86_64,
+ gpr_rbp_x86_64,
+ gpr_rsp_x86_64,
+ gpr_r8_x86_64,
+ gpr_r9_x86_64,
+ gpr_r10_x86_64,
+ gpr_r11_x86_64,
+ gpr_r12_x86_64,
+ gpr_r13_x86_64,
+ gpr_r14_x86_64,
+ gpr_r15_x86_64,
+ gpr_rip_x86_64,
+ gpr_rflags_x86_64,
+ gpr_cs_x86_64,
+ gpr_fs_x86_64,
+ gpr_gs_x86_64,
+ gpr_ss_x86_64,
+ gpr_ds_x86_64,
+ gpr_es_x86_64,
+ gpr_eax_x86_64,
+ gpr_ebx_x86_64,
+ gpr_ecx_x86_64,
+ gpr_edx_x86_64,
+ gpr_edi_x86_64,
+ gpr_esi_x86_64,
+ gpr_ebp_x86_64,
+ gpr_esp_x86_64,
+ gpr_r8d_x86_64, // Low 32 bits or r8
+ gpr_r9d_x86_64, // Low 32 bits or r9
+ gpr_r10d_x86_64, // Low 32 bits or r10
+ gpr_r11d_x86_64, // Low 32 bits or r11
+ gpr_r12d_x86_64, // Low 32 bits or r12
+ gpr_r13d_x86_64, // Low 32 bits or r13
+ gpr_r14d_x86_64, // Low 32 bits or r14
+ gpr_r15d_x86_64, // Low 32 bits or r15
+ gpr_ax_x86_64,
+ gpr_bx_x86_64,
+ gpr_cx_x86_64,
+ gpr_dx_x86_64,
+ gpr_di_x86_64,
+ gpr_si_x86_64,
+ gpr_bp_x86_64,
+ gpr_sp_x86_64,
+ gpr_r8w_x86_64, // Low 16 bits or r8
+ gpr_r9w_x86_64, // Low 16 bits or r9
+ gpr_r10w_x86_64, // Low 16 bits or r10
+ gpr_r11w_x86_64, // Low 16 bits or r11
+ gpr_r12w_x86_64, // Low 16 bits or r12
+ gpr_r13w_x86_64, // Low 16 bits or r13
+ gpr_r14w_x86_64, // Low 16 bits or r14
+ gpr_r15w_x86_64, // Low 16 bits or r15
+ gpr_ah_x86_64,
+ gpr_bh_x86_64,
+ gpr_ch_x86_64,
+ gpr_dh_x86_64,
+ gpr_al_x86_64,
+ gpr_bl_x86_64,
+ gpr_cl_x86_64,
+ gpr_dl_x86_64,
+ gpr_dil_x86_64,
+ gpr_sil_x86_64,
+ gpr_bpl_x86_64,
+ gpr_spl_x86_64,
+ gpr_r8l_x86_64, // Low 8 bits or r8
+ gpr_r9l_x86_64, // Low 8 bits or r9
+ gpr_r10l_x86_64, // Low 8 bits or r10
+ gpr_r11l_x86_64, // Low 8 bits or r11
+ gpr_r12l_x86_64, // Low 8 bits or r12
+ gpr_r13l_x86_64, // Low 8 bits or r13
+ gpr_r14l_x86_64, // Low 8 bits or r14
+ gpr_r15l_x86_64, // Low 8 bits or r15
+};
+static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) == k_num_gpr_registers_x86_64,
+ "g_gpr_regnums_x86_64 has wrong number of register infos");
+
+static const uint32_t
+g_fpu_regnums_x86_64[] =
+{
+ fpu_fctrl_x86_64,
+ fpu_fstat_x86_64,
+ fpu_ftag_x86_64,
+ fpu_fop_x86_64,
+ fpu_fiseg_x86_64,
+ fpu_fioff_x86_64,
+ fpu_foseg_x86_64,
+ fpu_fooff_x86_64,
+ fpu_mxcsr_x86_64,
+ fpu_mxcsrmask_x86_64,
+ fpu_st0_x86_64,
+ fpu_st1_x86_64,
+ fpu_st2_x86_64,
+ fpu_st3_x86_64,
+ fpu_st4_x86_64,
+ fpu_st5_x86_64,
+ fpu_st6_x86_64,
+ fpu_st7_x86_64,
+ fpu_mm0_x86_64,
+ fpu_mm1_x86_64,
+ fpu_mm2_x86_64,
+ fpu_mm3_x86_64,
+ fpu_mm4_x86_64,
+ fpu_mm5_x86_64,
+ fpu_mm6_x86_64,
+ fpu_mm7_x86_64,
+ fpu_xmm0_x86_64,
+ fpu_xmm1_x86_64,
+ fpu_xmm2_x86_64,
+ fpu_xmm3_x86_64,
+ fpu_xmm4_x86_64,
+ fpu_xmm5_x86_64,
+ fpu_xmm6_x86_64,
+ fpu_xmm7_x86_64,
+ fpu_xmm8_x86_64,
+ fpu_xmm9_x86_64,
+ fpu_xmm10_x86_64,
+ fpu_xmm11_x86_64,
+ fpu_xmm12_x86_64,
+ fpu_xmm13_x86_64,
+ fpu_xmm14_x86_64,
+ fpu_xmm15_x86_64
+};
+static_assert((sizeof(g_fpu_regnums_x86_64) / sizeof(g_fpu_regnums_x86_64[0])) == k_num_fpr_registers_x86_64,
+ "g_fpu_regnums_x86_64 has wrong number of register infos");
+
+static const uint32_t
+g_avx_regnums_x86_64[] =
+{
+ fpu_ymm0_x86_64,
+ fpu_ymm1_x86_64,
+ fpu_ymm2_x86_64,
+ fpu_ymm3_x86_64,
+ fpu_ymm4_x86_64,
+ fpu_ymm5_x86_64,
+ fpu_ymm6_x86_64,
+ fpu_ymm7_x86_64,
+ fpu_ymm8_x86_64,
+ fpu_ymm9_x86_64,
+ fpu_ymm10_x86_64,
+ fpu_ymm11_x86_64,
+ fpu_ymm12_x86_64,
+ fpu_ymm13_x86_64,
+ fpu_ymm14_x86_64,
+ fpu_ymm15_x86_64
+};
+static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) == k_num_avx_registers_x86_64,
+ "g_avx_regnums_x86_64 has wrong number of register infos");
+
+uint32_t RegisterContextPOSIX_x86::g_contained_eax[] = { gpr_eax_i386, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_ebx[] = { gpr_ebx_i386, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_ecx[] = { gpr_ecx_i386, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_edx[] = { gpr_edx_i386, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_edi[] = { gpr_edi_i386, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_esi[] = { gpr_esi_i386, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_ebp[] = { gpr_ebp_i386, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_esp[] = { gpr_esp_i386, LLDB_INVALID_REGNUM };
+
+uint32_t RegisterContextPOSIX_x86::g_invalidate_eax[] = { gpr_eax_i386, gpr_ax_i386, gpr_ah_i386, gpr_al_i386, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_ebx[] = { gpr_ebx_i386, gpr_bx_i386, gpr_bh_i386, gpr_bl_i386, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_ecx[] = { gpr_ecx_i386, gpr_cx_i386, gpr_ch_i386, gpr_cl_i386, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_edx[] = { gpr_edx_i386, gpr_dx_i386, gpr_dh_i386, gpr_dl_i386, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_edi[] = { gpr_edi_i386, gpr_di_i386, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_esi[] = { gpr_esi_i386, gpr_si_i386, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_ebp[] = { gpr_ebp_i386, gpr_bp_i386, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_esp[] = { gpr_esp_i386, gpr_sp_i386, LLDB_INVALID_REGNUM };
+
+uint32_t RegisterContextPOSIX_x86::g_contained_rax[] = { gpr_rax_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_rbx[] = { gpr_rbx_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_rcx[] = { gpr_rcx_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_rdx[] = { gpr_rdx_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_rdi[] = { gpr_rdi_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_rsi[] = { gpr_rsi_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_rbp[] = { gpr_rbp_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_rsp[] = { gpr_rsp_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_r8[] = { gpr_r8_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_r9[] = { gpr_r9_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_r10[] = { gpr_r10_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_r11[] = { gpr_r11_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_r12[] = { gpr_r12_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_r13[] = { gpr_r13_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_r14[] = { gpr_r14_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_contained_r15[] = { gpr_r15_x86_64, LLDB_INVALID_REGNUM };
+
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rax[] = { gpr_rax_x86_64, gpr_eax_x86_64, gpr_ax_x86_64, gpr_ah_x86_64, gpr_al_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rbx[] = { gpr_rbx_x86_64, gpr_ebx_x86_64, gpr_bx_x86_64, gpr_bh_x86_64, gpr_bl_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rcx[] = { gpr_rcx_x86_64, gpr_ecx_x86_64, gpr_cx_x86_64, gpr_ch_x86_64, gpr_cl_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rdx[] = { gpr_rdx_x86_64, gpr_edx_x86_64, gpr_dx_x86_64, gpr_dh_x86_64, gpr_dl_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rdi[] = { gpr_rdi_x86_64, gpr_edi_x86_64, gpr_di_x86_64, gpr_dil_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rsi[] = { gpr_rsi_x86_64, gpr_esi_x86_64, gpr_si_x86_64, gpr_sil_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rbp[] = { gpr_rbp_x86_64, gpr_ebp_x86_64, gpr_bp_x86_64, gpr_bpl_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_rsp[] = { gpr_rsp_x86_64, gpr_esp_x86_64, gpr_sp_x86_64, gpr_spl_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r8[] = { gpr_r8_x86_64, gpr_r8d_x86_64, gpr_r8w_x86_64, gpr_r8l_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r9[] = { gpr_r9_x86_64, gpr_r9d_x86_64, gpr_r9w_x86_64, gpr_r9l_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r10[] = { gpr_r10_x86_64, gpr_r10d_x86_64, gpr_r10w_x86_64, gpr_r10l_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r11[] = { gpr_r11_x86_64, gpr_r11d_x86_64, gpr_r11w_x86_64, gpr_r11l_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r12[] = { gpr_r12_x86_64, gpr_r12d_x86_64, gpr_r12w_x86_64, gpr_r12l_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r13[] = { gpr_r13_x86_64, gpr_r13d_x86_64, gpr_r13w_x86_64, gpr_r13l_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r14[] = { gpr_r14_x86_64, gpr_r14d_x86_64, gpr_r14w_x86_64, gpr_r14l_x86_64, LLDB_INVALID_REGNUM };
+uint32_t RegisterContextPOSIX_x86::g_invalidate_r15[] = { gpr_r15_x86_64, gpr_r15d_x86_64, gpr_r15w_x86_64, gpr_r15l_x86_64, LLDB_INVALID_REGNUM };
+
+// Number of register sets provided by this context.
+enum
+{
+ k_num_extended_register_sets = 1,
+ k_num_register_sets = 3
+};
+
+static const RegisterSet
+g_reg_sets_i386[k_num_register_sets] =
+{
+ { "General Purpose Registers", "gpr", k_num_gpr_registers_i386, g_gpr_regnums_i386 },
+ { "Floating Point Registers", "fpu", k_num_fpr_registers_i386, g_fpu_regnums_i386 },
+ { "Advanced Vector Extensions", "avx", k_num_avx_registers_i386, g_avx_regnums_i386 }
+};
+
+static const RegisterSet
+g_reg_sets_x86_64[k_num_register_sets] =
+{
+ { "General Purpose Registers", "gpr", k_num_gpr_registers_x86_64, g_gpr_regnums_x86_64 },
+ { "Floating Point Registers", "fpu", k_num_fpr_registers_x86_64, g_fpu_regnums_x86_64 },
+ { "Advanced Vector Extensions", "avx", k_num_avx_registers_x86_64, g_avx_regnums_x86_64 }
+};
+
+bool RegisterContextPOSIX_x86::IsGPR(unsigned reg)
+{
+ return reg <= m_reg_info.last_gpr; // GPR's come first.
+}
+
+bool RegisterContextPOSIX_x86::IsFPR(unsigned reg)
+{
+ return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
+}
+
+bool RegisterContextPOSIX_x86::IsAVX(unsigned reg)
+{
+ return (m_reg_info.first_ymm <= reg && reg <= m_reg_info.last_ymm);
+}
+
+bool RegisterContextPOSIX_x86::IsFPR(unsigned reg, FPRType fpr_type)
+{
+ bool generic_fpr = IsFPR(reg);
+
+ if (fpr_type == eXSAVE)
+ return generic_fpr || IsAVX(reg);
+ return generic_fpr;
+}
+
+RegisterContextPOSIX_x86::RegisterContextPOSIX_x86(Thread &thread,
+ uint32_t concrete_frame_idx,
+ RegisterInfoInterface *register_info)
+ : RegisterContext(thread, concrete_frame_idx)
+{
+ m_register_info_ap.reset(register_info);
+
+ switch (register_info->m_target_arch.GetCore())
+ {
+ case ArchSpec::eCore_x86_32_i386:
+ case ArchSpec::eCore_x86_32_i486:
+ case ArchSpec::eCore_x86_32_i486sx:
+ m_reg_info.num_registers = k_num_registers_i386;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_i386;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_i386;
+ m_reg_info.num_avx_registers = k_num_avx_registers_i386;
+ m_reg_info.last_gpr = k_last_gpr_i386;
+ m_reg_info.first_fpr = k_first_fpr_i386;
+ m_reg_info.last_fpr = k_last_fpr_i386;
+ m_reg_info.first_st = fpu_st0_i386;
+ m_reg_info.last_st = fpu_st7_i386;
+ m_reg_info.first_mm = fpu_mm0_i386;
+ m_reg_info.last_mm = fpu_mm7_i386;
+ m_reg_info.first_xmm = fpu_xmm0_i386;
+ m_reg_info.last_xmm = fpu_xmm7_i386;
+ m_reg_info.first_ymm = fpu_ymm0_i386;
+ m_reg_info.last_ymm = fpu_ymm7_i386;
+ m_reg_info.first_dr = dr0_i386;
+ m_reg_info.gpr_flags = gpr_eflags_i386;
+ break;
+ case ArchSpec::eCore_x86_64_x86_64:
+ m_reg_info.num_registers = k_num_registers_x86_64;
+ m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64;
+ m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64;
+ m_reg_info.num_avx_registers = k_num_avx_registers_x86_64;
+ m_reg_info.last_gpr = k_last_gpr_x86_64;
+ m_reg_info.first_fpr = k_first_fpr_x86_64;
+ m_reg_info.last_fpr = k_last_fpr_x86_64;
+ m_reg_info.first_st = fpu_st0_x86_64;
+ m_reg_info.last_st = fpu_st7_x86_64;
+ m_reg_info.first_mm = fpu_mm0_x86_64;
+ m_reg_info.last_mm = fpu_mm7_x86_64;
+ m_reg_info.first_xmm = fpu_xmm0_x86_64;
+ m_reg_info.last_xmm = fpu_xmm15_x86_64;
+ m_reg_info.first_ymm = fpu_ymm0_x86_64;
+ m_reg_info.last_ymm = fpu_ymm15_x86_64;
+ m_reg_info.first_dr = dr0_x86_64;
+ m_reg_info.gpr_flags = gpr_rflags_x86_64;
+ break;
+ default:
+ assert(false && "Unhandled target architecture.");
+ break;
+ }
+
+ // Initialize m_iovec to point to the buffer and buffer size
+ // using the conventions of Berkeley style UIO structures, as required
+ // by PTRACE extensions.
+ m_iovec.iov_base = &m_fpr.xstate.xsave;
+ m_iovec.iov_len = sizeof(m_fpr.xstate.xsave);
+
+ ::memset(&m_fpr, 0, sizeof(FPR));
+
+ // elf-core yet to support ReadFPR()
+ ProcessSP base = CalculateProcess();
+ if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
+ return;
+
+ m_fpr_type = eNotValid;
+}
+
+RegisterContextPOSIX_x86::~RegisterContextPOSIX_x86()
+{
+}
+
+RegisterContextPOSIX_x86::FPRType RegisterContextPOSIX_x86::GetFPRType()
+{
+ if (m_fpr_type == eNotValid)
+ {
+ // TODO: Use assembly to call cpuid on the inferior and query ebx or ecx
+ m_fpr_type = eXSAVE; // extended floating-point registers, if available
+ if (false == ReadFPR())
+ m_fpr_type = eFXSAVE; // assume generic floating-point registers
+ }
+ return m_fpr_type;
+}
+
+void
+RegisterContextPOSIX_x86::Invalidate()
+{
+}
+
+void
+RegisterContextPOSIX_x86::InvalidateAllRegisters()
+{
+}
+
+unsigned
+RegisterContextPOSIX_x86::GetRegisterOffset(unsigned reg)
+{
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_offset;
+}
+
+unsigned
+RegisterContextPOSIX_x86::GetRegisterSize(unsigned reg)
+{
+ assert(reg < m_reg_info.num_registers && "Invalid register number.");
+ return GetRegisterInfo()[reg].byte_size;
+}
+
+size_t
+RegisterContextPOSIX_x86::GetRegisterCount()
+{
+ size_t num_registers = m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
+ if (GetFPRType() == eXSAVE)
+ return num_registers + m_reg_info.num_avx_registers;
+ return num_registers;
+}
+
+size_t
+RegisterContextPOSIX_x86::GetGPRSize()
+{
+ return m_register_info_ap->GetGPRSize ();
+}
+
+const RegisterInfo *
+RegisterContextPOSIX_x86::GetRegisterInfo()
+{
+ // Commonly, this method is overridden and g_register_infos is copied and specialized.
+ // So, use GetRegisterInfo() rather than g_register_infos in this scope.
+ return m_register_info_ap->GetRegisterInfo ();
+}
+
+const RegisterInfo *
+RegisterContextPOSIX_x86::GetRegisterInfoAtIndex(size_t reg)
+{
+ if (reg < m_reg_info.num_registers)
+ return &GetRegisterInfo()[reg];
+ else
+ return NULL;
+}
+
+size_t
+RegisterContextPOSIX_x86::GetRegisterSetCount()
+{
+ size_t sets = 0;
+ for (size_t set = 0; set < k_num_register_sets; ++set)
+ {
+ if (IsRegisterSetAvailable(set))
+ ++sets;
+ }
+
+ return sets;
+}
+
+const RegisterSet *
+RegisterContextPOSIX_x86::GetRegisterSet(size_t set)
+{
+ if (IsRegisterSetAvailable(set))
+ {
+ switch (m_register_info_ap->m_target_arch.GetCore())
+ {
+ case ArchSpec::eCore_x86_32_i386:
+ case ArchSpec::eCore_x86_32_i486:
+ case ArchSpec::eCore_x86_32_i486sx:
+ return &g_reg_sets_i386[set];
+ case ArchSpec::eCore_x86_64_x86_64:
+ return &g_reg_sets_x86_64[set];
+ default:
+ assert(false && "Unhandled target architecture.");
+ return NULL;
+ }
+ }
+ return NULL;
+}
+
+const char *
+RegisterContextPOSIX_x86::GetRegisterName(unsigned reg)
+{
+ assert(reg < m_reg_info.num_registers && "Invalid register offset.");
+ return GetRegisterInfo()[reg].name;
+}
+
+lldb::ByteOrder
+RegisterContextPOSIX_x86::GetByteOrder()
+{
+ // Get the target process whose privileged thread was used for the register read.
+ lldb::ByteOrder byte_order = eByteOrderInvalid;
+ Process *process = CalculateProcess().get();
+
+ if (process)
+ byte_order = process->GetByteOrder();
+ return byte_order;
+}
+
+// Parse ymm registers and into xmm.bytes and ymmh.bytes.
+bool RegisterContextPOSIX_x86::CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order)
+{
+ if (!IsAVX(reg))
+ return false;
+
+ if (byte_order == eByteOrderLittle)
+ {
+ ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
+ sizeof(XMMReg));
+ ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
+ sizeof(YMMHReg));
+ return true;
+ }
+
+ if (byte_order == eByteOrderBig)
+ {
+ ::memcpy(m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
+ sizeof(XMMReg));
+ ::memcpy(m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
+ sizeof(YMMHReg));
+ return true;
+ }
+ return false; // unsupported or invalid byte order
+}
+
+// Concatenate xmm.bytes with ymmh.bytes
+bool RegisterContextPOSIX_x86::CopyXSTATEtoYMM(uint32_t reg, lldb::ByteOrder byte_order)
+{
+ if (!IsAVX(reg))
+ return false;
+
+ if (byte_order == eByteOrderLittle)
+ {
+ ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
+ m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ sizeof(XMMReg));
+ ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
+ m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ sizeof(YMMHReg));
+ return true;
+ }
+
+ if (byte_order == eByteOrderBig)
+ {
+ ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes + sizeof(XMMReg),
+ m_fpr.xstate.fxsave.xmm[reg - m_reg_info.first_ymm].bytes,
+ sizeof(XMMReg));
+ ::memcpy(m_ymm_set.ymm[reg - m_reg_info.first_ymm].bytes,
+ m_fpr.xstate.xsave.ymmh[reg - m_reg_info.first_ymm].bytes,
+ sizeof(YMMHReg));
+ return true;
+ }
+ return false; // unsupported or invalid byte order
+}
+
+bool
+RegisterContextPOSIX_x86::IsRegisterSetAvailable(size_t set_index)
+{
+ // Note: Extended register sets are assumed to be at the end of g_reg_sets...
+ size_t num_sets = k_num_register_sets - k_num_extended_register_sets;
+
+ if (GetFPRType() == eXSAVE) // ...and to start with AVX registers.
+ ++num_sets;
+ return (set_index < num_sets);
+}
+
+
+// Used when parsing DWARF and EH frame information and any other
+// object file sections that contain register numbers in them.
+uint32_t
+RegisterContextPOSIX_x86::ConvertRegisterKindToRegisterNumber(uint32_t kind,
+ uint32_t num)
+{
+ const uint32_t num_regs = GetRegisterCount();
+
+ assert (kind < kNumRegisterKinds);
+ for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
+ {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
+
+ if (reg_info->kinds[kind] == num)
+ return reg_idx;
+ }
+
+ return LLDB_INVALID_REGNUM;
+}
+
diff --git a/source/Plugins/Process/POSIX/RegisterContextPOSIX_x86.h b/source/Plugins/Process/POSIX/RegisterContextPOSIX_x86.h
new file mode 100644
index 000000000000..5e922025b830
--- /dev/null
+++ b/source/Plugins/Process/POSIX/RegisterContextPOSIX_x86.h
@@ -0,0 +1,462 @@
+//===-- RegisterContextPOSIX_x86.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_RegisterContextPOSIX_x86_H_
+#define liblldb_RegisterContextPOSIX_x86_H_
+
+#include "lldb/Core/Log.h"
+#include "RegisterContextPOSIX.h"
+#include "RegisterContext_x86.h"
+
+class ProcessMonitor;
+
+//---------------------------------------------------------------------------
+// Internal codes for all i386 registers.
+//---------------------------------------------------------------------------
+enum
+{
+ k_first_gpr_i386,
+ gpr_eax_i386 = k_first_gpr_i386,
+ gpr_ebx_i386,
+ gpr_ecx_i386,
+ gpr_edx_i386,
+ gpr_edi_i386,
+ gpr_esi_i386,
+ gpr_ebp_i386,
+ gpr_esp_i386,
+ gpr_eip_i386,
+ gpr_eflags_i386,
+ gpr_cs_i386,
+ gpr_fs_i386,
+ gpr_gs_i386,
+ gpr_ss_i386,
+ gpr_ds_i386,
+ gpr_es_i386,
+
+ k_first_alias_i386,
+ gpr_ax_i386 = k_first_alias_i386,
+ gpr_bx_i386,
+ gpr_cx_i386,
+ gpr_dx_i386,
+ gpr_di_i386,
+ gpr_si_i386,
+ gpr_bp_i386,
+ gpr_sp_i386,
+ gpr_ah_i386,
+ gpr_bh_i386,
+ gpr_ch_i386,
+ gpr_dh_i386,
+ gpr_al_i386,
+ gpr_bl_i386,
+ gpr_cl_i386,
+ gpr_dl_i386,
+ k_last_alias_i386 = gpr_dl_i386,
+
+ k_last_gpr_i386 = k_last_alias_i386,
+
+ k_first_fpr_i386,
+ fpu_fctrl_i386 = k_first_fpr_i386,
+ fpu_fstat_i386,
+ fpu_ftag_i386,
+ fpu_fop_i386,
+ fpu_fiseg_i386,
+ fpu_fioff_i386,
+ fpu_foseg_i386,
+ fpu_fooff_i386,
+ fpu_mxcsr_i386,
+ fpu_mxcsrmask_i386,
+ fpu_st0_i386,
+ fpu_st1_i386,
+ fpu_st2_i386,
+ fpu_st3_i386,
+ fpu_st4_i386,
+ fpu_st5_i386,
+ fpu_st6_i386,
+ fpu_st7_i386,
+ fpu_mm0_i386,
+ fpu_mm1_i386,
+ fpu_mm2_i386,
+ fpu_mm3_i386,
+ fpu_mm4_i386,
+ fpu_mm5_i386,
+ fpu_mm6_i386,
+ fpu_mm7_i386,
+ fpu_xmm0_i386,
+ fpu_xmm1_i386,
+ fpu_xmm2_i386,
+ fpu_xmm3_i386,
+ fpu_xmm4_i386,
+ fpu_xmm5_i386,
+ fpu_xmm6_i386,
+ fpu_xmm7_i386,
+ k_last_fpr_i386 = fpu_xmm7_i386,
+
+ k_first_avx_i386,
+ fpu_ymm0_i386 = k_first_avx_i386,
+ fpu_ymm1_i386,
+ fpu_ymm2_i386,
+ fpu_ymm3_i386,
+ fpu_ymm4_i386,
+ fpu_ymm5_i386,
+ fpu_ymm6_i386,
+ fpu_ymm7_i386,
+ k_last_avx_i386 = fpu_ymm7_i386,
+
+ dr0_i386,
+ dr1_i386,
+ dr2_i386,
+ dr3_i386,
+ dr4_i386,
+ dr5_i386,
+ dr6_i386,
+ dr7_i386,
+
+ k_num_registers_i386,
+ k_num_gpr_registers_i386 = k_last_gpr_i386 - k_first_gpr_i386 + 1,
+ k_num_fpr_registers_i386 = k_last_fpr_i386 - k_first_fpr_i386 + 1,
+ k_num_avx_registers_i386 = k_last_avx_i386 - k_first_avx_i386 + 1
+};
+
+//---------------------------------------------------------------------------
+// Internal codes for all x86_64 registers.
+//---------------------------------------------------------------------------
+enum
+{
+ k_first_gpr_x86_64,
+ gpr_rax_x86_64 = k_first_gpr_x86_64,
+ gpr_rbx_x86_64,
+ gpr_rcx_x86_64,
+ gpr_rdx_x86_64,
+ gpr_rdi_x86_64,
+ gpr_rsi_x86_64,
+ gpr_rbp_x86_64,
+ gpr_rsp_x86_64,
+ gpr_r8_x86_64,
+ gpr_r9_x86_64,
+ gpr_r10_x86_64,
+ gpr_r11_x86_64,
+ gpr_r12_x86_64,
+ gpr_r13_x86_64,
+ gpr_r14_x86_64,
+ gpr_r15_x86_64,
+ gpr_rip_x86_64,
+ gpr_rflags_x86_64,
+ gpr_cs_x86_64,
+ gpr_fs_x86_64,
+ gpr_gs_x86_64,
+ gpr_ss_x86_64,
+ gpr_ds_x86_64,
+ gpr_es_x86_64,
+
+ k_first_alias_x86_64,
+ gpr_eax_x86_64 = k_first_alias_x86_64,
+ gpr_ebx_x86_64,
+ gpr_ecx_x86_64,
+ gpr_edx_x86_64,
+ gpr_edi_x86_64,
+ gpr_esi_x86_64,
+ gpr_ebp_x86_64,
+ gpr_esp_x86_64,
+ gpr_r8d_x86_64, // Low 32 bits of r8
+ gpr_r9d_x86_64, // Low 32 bits of r9
+ gpr_r10d_x86_64, // Low 32 bits of r10
+ gpr_r11d_x86_64, // Low 32 bits of r11
+ gpr_r12d_x86_64, // Low 32 bits of r12
+ gpr_r13d_x86_64, // Low 32 bits of r13
+ gpr_r14d_x86_64, // Low 32 bits of r14
+ gpr_r15d_x86_64, // Low 32 bits of r15
+ gpr_ax_x86_64,
+ gpr_bx_x86_64,
+ gpr_cx_x86_64,
+ gpr_dx_x86_64,
+ gpr_di_x86_64,
+ gpr_si_x86_64,
+ gpr_bp_x86_64,
+ gpr_sp_x86_64,
+ gpr_r8w_x86_64, // Low 16 bits of r8
+ gpr_r9w_x86_64, // Low 16 bits of r9
+ gpr_r10w_x86_64, // Low 16 bits of r10
+ gpr_r11w_x86_64, // Low 16 bits of r11
+ gpr_r12w_x86_64, // Low 16 bits of r12
+ gpr_r13w_x86_64, // Low 16 bits of r13
+ gpr_r14w_x86_64, // Low 16 bits of r14
+ gpr_r15w_x86_64, // Low 16 bits of r15
+ gpr_ah_x86_64,
+ gpr_bh_x86_64,
+ gpr_ch_x86_64,
+ gpr_dh_x86_64,
+ gpr_al_x86_64,
+ gpr_bl_x86_64,
+ gpr_cl_x86_64,
+ gpr_dl_x86_64,
+ gpr_dil_x86_64,
+ gpr_sil_x86_64,
+ gpr_bpl_x86_64,
+ gpr_spl_x86_64,
+ gpr_r8l_x86_64, // Low 8 bits of r8
+ gpr_r9l_x86_64, // Low 8 bits of r9
+ gpr_r10l_x86_64, // Low 8 bits of r10
+ gpr_r11l_x86_64, // Low 8 bits of r11
+ gpr_r12l_x86_64, // Low 8 bits of r12
+ gpr_r13l_x86_64, // Low 8 bits of r13
+ gpr_r14l_x86_64, // Low 8 bits of r14
+ gpr_r15l_x86_64, // Low 8 bits of r15
+ k_last_alias_x86_64 = gpr_r15l_x86_64,
+
+ k_last_gpr_x86_64 = k_last_alias_x86_64,
+
+ k_first_fpr_x86_64,
+ fpu_fctrl_x86_64 = k_first_fpr_x86_64,
+ fpu_fstat_x86_64,
+ fpu_ftag_x86_64,
+ fpu_fop_x86_64,
+ fpu_fiseg_x86_64,
+ fpu_fioff_x86_64,
+ fpu_foseg_x86_64,
+ fpu_fooff_x86_64,
+ fpu_mxcsr_x86_64,
+ fpu_mxcsrmask_x86_64,
+ fpu_st0_x86_64,
+ fpu_st1_x86_64,
+ fpu_st2_x86_64,
+ fpu_st3_x86_64,
+ fpu_st4_x86_64,
+ fpu_st5_x86_64,
+ fpu_st6_x86_64,
+ fpu_st7_x86_64,
+ fpu_mm0_x86_64,
+ fpu_mm1_x86_64,
+ fpu_mm2_x86_64,
+ fpu_mm3_x86_64,
+ fpu_mm4_x86_64,
+ fpu_mm5_x86_64,
+ fpu_mm6_x86_64,
+ fpu_mm7_x86_64,
+ fpu_xmm0_x86_64,
+ fpu_xmm1_x86_64,
+ fpu_xmm2_x86_64,
+ fpu_xmm3_x86_64,
+ fpu_xmm4_x86_64,
+ fpu_xmm5_x86_64,
+ fpu_xmm6_x86_64,
+ fpu_xmm7_x86_64,
+ fpu_xmm8_x86_64,
+ fpu_xmm9_x86_64,
+ fpu_xmm10_x86_64,
+ fpu_xmm11_x86_64,
+ fpu_xmm12_x86_64,
+ fpu_xmm13_x86_64,
+ fpu_xmm14_x86_64,
+ fpu_xmm15_x86_64,
+ k_last_fpr_x86_64 = fpu_xmm15_x86_64,
+
+ k_first_avx_x86_64,
+ fpu_ymm0_x86_64 = k_first_avx_x86_64,
+ fpu_ymm1_x86_64,
+ fpu_ymm2_x86_64,
+ fpu_ymm3_x86_64,
+ fpu_ymm4_x86_64,
+ fpu_ymm5_x86_64,
+ fpu_ymm6_x86_64,
+ fpu_ymm7_x86_64,
+ fpu_ymm8_x86_64,
+ fpu_ymm9_x86_64,
+ fpu_ymm10_x86_64,
+ fpu_ymm11_x86_64,
+ fpu_ymm12_x86_64,
+ fpu_ymm13_x86_64,
+ fpu_ymm14_x86_64,
+ fpu_ymm15_x86_64,
+ k_last_avx_x86_64 = fpu_ymm15_x86_64,
+
+ dr0_x86_64,
+ dr1_x86_64,
+ dr2_x86_64,
+ dr3_x86_64,
+ dr4_x86_64,
+ dr5_x86_64,
+ dr6_x86_64,
+ dr7_x86_64,
+
+ k_num_registers_x86_64,
+ k_num_gpr_registers_x86_64 = k_last_gpr_x86_64 - k_first_gpr_x86_64 + 1,
+ k_num_fpr_registers_x86_64 = k_last_fpr_x86_64 - k_first_fpr_x86_64 + 1,
+ k_num_avx_registers_x86_64 = k_last_avx_x86_64 - k_first_avx_x86_64 + 1
+};
+
+class RegisterContextPOSIX_x86
+ : public lldb_private::RegisterContext
+{
+public:
+ RegisterContextPOSIX_x86 (lldb_private::Thread &thread,
+ uint32_t concrete_frame_idx,
+ RegisterInfoInterface *register_info);
+
+ ~RegisterContextPOSIX_x86();
+
+ void
+ Invalidate();
+
+ void
+ InvalidateAllRegisters();
+
+ size_t
+ GetRegisterCount();
+
+ virtual size_t
+ GetGPRSize();
+
+ virtual unsigned
+ GetRegisterSize(unsigned reg);
+
+ virtual unsigned
+ GetRegisterOffset(unsigned reg);
+
+ const lldb_private::RegisterInfo *
+ GetRegisterInfoAtIndex(size_t reg);
+
+ size_t
+ GetRegisterSetCount();
+
+ const lldb_private::RegisterSet *
+ GetRegisterSet(size_t set);
+
+ const char *
+ GetRegisterName(unsigned reg);
+
+ uint32_t
+ ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num);
+
+ //---------------------------------------------------------------------------
+ // Note: prefer kernel definitions over user-land
+ //---------------------------------------------------------------------------
+ enum FPRType
+ {
+ eNotValid = 0,
+ eFSAVE, // TODO
+ eFXSAVE,
+ eSOFT, // TODO
+ eXSAVE
+ };
+
+ static uint32_t g_contained_eax[];
+ static uint32_t g_contained_ebx[];
+ static uint32_t g_contained_ecx[];
+ static uint32_t g_contained_edx[];
+ static uint32_t g_contained_edi[];
+ static uint32_t g_contained_esi[];
+ static uint32_t g_contained_ebp[];
+ static uint32_t g_contained_esp[];
+
+ static uint32_t g_invalidate_eax[];
+ static uint32_t g_invalidate_ebx[];
+ static uint32_t g_invalidate_ecx[];
+ static uint32_t g_invalidate_edx[];
+ static uint32_t g_invalidate_edi[];
+ static uint32_t g_invalidate_esi[];
+ static uint32_t g_invalidate_ebp[];
+ static uint32_t g_invalidate_esp[];
+
+ static uint32_t g_contained_rax[];
+ static uint32_t g_contained_rbx[];
+ static uint32_t g_contained_rcx[];
+ static uint32_t g_contained_rdx[];
+ static uint32_t g_contained_rdi[];
+ static uint32_t g_contained_rsi[];
+ static uint32_t g_contained_rbp[];
+ static uint32_t g_contained_rsp[];
+ static uint32_t g_contained_r8[];
+ static uint32_t g_contained_r9[];
+ static uint32_t g_contained_r10[];
+ static uint32_t g_contained_r11[];
+ static uint32_t g_contained_r12[];
+ static uint32_t g_contained_r13[];
+ static uint32_t g_contained_r14[];
+ static uint32_t g_contained_r15[];
+
+ static uint32_t g_invalidate_rax[];
+ static uint32_t g_invalidate_rbx[];
+ static uint32_t g_invalidate_rcx[];
+ static uint32_t g_invalidate_rdx[];
+ static uint32_t g_invalidate_rdi[];
+ static uint32_t g_invalidate_rsi[];
+ static uint32_t g_invalidate_rbp[];
+ static uint32_t g_invalidate_rsp[];
+ static uint32_t g_invalidate_r8[];
+ static uint32_t g_invalidate_r9[];
+ static uint32_t g_invalidate_r10[];
+ static uint32_t g_invalidate_r11[];
+ static uint32_t g_invalidate_r12[];
+ static uint32_t g_invalidate_r13[];
+ static uint32_t g_invalidate_r14[];
+ static uint32_t g_invalidate_r15[];
+
+protected:
+ struct RegInfo
+ {
+ uint32_t num_registers;
+ uint32_t num_gpr_registers;
+ uint32_t num_fpr_registers;
+ uint32_t num_avx_registers;
+
+ uint32_t last_gpr;
+ uint32_t first_fpr;
+ uint32_t last_fpr;
+
+ uint32_t first_st;
+ uint32_t last_st;
+ uint32_t first_mm;
+ uint32_t last_mm;
+ uint32_t first_xmm;
+ uint32_t last_xmm;
+ uint32_t first_ymm;
+ uint32_t last_ymm;
+
+ uint32_t first_dr;
+ uint32_t gpr_flags;
+ };
+
+ uint64_t m_gpr_x86_64[k_num_gpr_registers_x86_64]; // 64-bit general purpose registers.
+ RegInfo m_reg_info;
+ FPRType m_fpr_type; // determines the type of data stored by union FPR, if any.
+ FPR m_fpr; // floating-point registers including extended register sets.
+ IOVEC m_iovec; // wrapper for xsave.
+ YMM m_ymm_set; // copy of ymmh and xmm register halves.
+ std::unique_ptr<RegisterInfoInterface> m_register_info_ap; // Register Info Interface (FreeBSD or Linux)
+
+ // Determines if an extended register set is supported on the processor running the inferior process.
+ virtual bool
+ IsRegisterSetAvailable(size_t set_index);
+
+ virtual const lldb_private::RegisterInfo *
+ GetRegisterInfo();
+
+ bool
+ IsGPR(unsigned reg);
+
+ bool
+ IsFPR(unsigned reg);
+
+ bool
+ IsAVX(unsigned reg);
+
+ lldb::ByteOrder GetByteOrder();
+
+ bool CopyXSTATEtoYMM(uint32_t reg, lldb::ByteOrder byte_order);
+ bool CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order);
+ bool IsFPR(unsigned reg, FPRType fpr_type);
+ FPRType GetFPRType();
+
+ virtual bool ReadGPR() = 0;
+ virtual bool ReadFPR() = 0;
+ virtual bool WriteGPR() = 0;
+ virtual bool WriteFPR() = 0;
+};
+
+#endif // #ifndef liblldb_RegisterContextPOSIX_x86_H_
diff --git a/source/Plugins/Process/POSIX/RegisterContext_i386.cpp b/source/Plugins/Process/POSIX/RegisterContext_i386.cpp
deleted file mode 100644
index 49676bd3fc73..000000000000
--- a/source/Plugins/Process/POSIX/RegisterContext_i386.cpp
+++ /dev/null
@@ -1,551 +0,0 @@
-//===-- RegisterContextPOSIX_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 "llvm/Support/Compiler.h"
-
-#include "ProcessPOSIX.h"
-#include "ProcessPOSIXLog.h"
-#include "ProcessMonitor.h"
-#include "RegisterContext_i386.h"
-#include "RegisterContext_x86.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,
-#ifdef __FreeBSD__
- gpr_orig_ax,
-#endif
- 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
-};
-
-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,
-#ifdef __FreeBSD__
- gpr_orig_ax,
-#endif
- 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(RegisterContext_i386::UserArea, regs) + \
- offsetof(RegisterContext_i386::GPR, regname))
-
-// Computes the offset of the given FPR in the user data area.
-#define FPR_OFFSET(regname) \
- (offsetof(RegisterContext_i386::UserArea, i387) + \
- offsetof(RegisterContext_i386::FPU, regname))
-
-// Number of bytes needed to represent a GPR.
-#define GPR_SIZE(reg) sizeof(((RegisterContext_i386::GPR*)NULL)->reg)
-
-// Number of bytes needed to represent a FPR.
-#define FPR_SIZE(reg) sizeof(((RegisterContext_i386::FPU*)NULL)->reg)
-
-// Number of bytes needed to represent the i'th FP register.
-#define FP_SIZE sizeof(((RegisterContext_i386::MMSReg*)NULL)->bytes)
-
-// Number of bytes needed to represent an XMM register.
-#define XMM_SIZE sizeof(RegisterContext_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 }, NULL, NULL }
-
-#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) \
- { #reg#i, NULL, FP_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { dwarf_##reg##i, dwarf_##reg##i, \
- LLDB_INVALID_REGNUM, gdb_##reg##i, fpu_##reg##i }, NULL, NULL }
-
-#define DEFINE_XMM(reg, i) \
- { #reg#i, NULL, XMM_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { dwarf_##reg##i, dwarf_##reg##i, \
- LLDB_INVALID_REGNUM, gdb_##reg##i, fpu_##reg##i }, NULL, NULL }
-
-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),
-
-};
-
-#ifndef NDEBUG
-static size_t k_num_register_infos = (sizeof(g_register_infos)/sizeof(RegisterInfo));
-#endif
-
-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;
-}
-
-RegisterContext_i386::RegisterContext_i386(Thread &thread,
- uint32_t concrete_frame_idx)
- : RegisterContextPOSIX(thread, concrete_frame_idx)
-{
-}
-
-RegisterContext_i386::~RegisterContext_i386()
-{
-}
-
-ProcessMonitor &
-RegisterContext_i386::GetMonitor()
-{
- ProcessSP base = CalculateProcess();
- ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get());
- return process->GetMonitor();
-}
-
-void
-RegisterContext_i386::Invalidate()
-{
-}
-
-void
-RegisterContext_i386::InvalidateAllRegisters()
-{
-}
-
-size_t
-RegisterContext_i386::GetRegisterCount()
-{
- assert(k_num_register_infos == k_num_registers);
- return k_num_registers;
-}
-
-const RegisterInfo *
-RegisterContext_i386::GetRegisterInfoAtIndex(size_t reg)
-{
- assert(k_num_register_infos == k_num_registers);
- if (reg < k_num_registers)
- return &g_register_infos[reg];
- else
- return NULL;
-}
-
-size_t
-RegisterContext_i386::GetRegisterSetCount()
-{
- return k_num_register_sets;
-}
-
-const RegisterSet *
-RegisterContext_i386::GetRegisterSet(size_t set)
-{
- if (set < k_num_register_sets)
- return &g_reg_sets[set];
- else
- return NULL;
-}
-
-unsigned
-RegisterContext_i386::GetRegisterIndexFromOffset(unsigned offset)
-{
- unsigned reg;
- for (reg = 0; reg < k_num_registers; reg++)
- {
- if (g_register_infos[reg].byte_offset == offset)
- break;
- }
- assert(reg < k_num_registers && "Invalid register offset.");
- return reg;
-}
-
-const char *
-RegisterContext_i386::GetRegisterName(unsigned reg)
-{
- assert(reg < k_num_registers && "Invalid register offset.");
- return g_register_infos[reg].name;
-}
-
-bool
-RegisterContext_i386::ReadRegister(const RegisterInfo *reg_info,
- RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadRegisterValue(m_thread.GetID(), GetRegOffset(reg),
- GetRegisterName(reg), GetRegSize(reg), value);
-}
-
-bool
-RegisterContext_i386::ReadAllRegisterValues(DataBufferSP &data_sp)
-{
- return false;
-}
-
-bool RegisterContext_i386::WriteRegister(const RegisterInfo *reg_info,
- const RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteRegisterValue(m_thread.GetID(), GetRegOffset(reg),
- GetRegisterName(reg), value);
-}
-
-bool
-RegisterContext_i386::WriteAllRegisterValues(const DataBufferSP &data)
-{
- return false;
-}
-
-bool
-RegisterContext_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
-RegisterContext_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
-RegisterContext_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);
-}
-
-void
-RegisterContext_i386::LogGPR(const char *title)
-{
- Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
- if (log)
- {
- if (title)
- log->Printf ("%s", title);
- for (uint32_t i=0; i<k_num_gpr_registers; i++)
- {
- uint32_t reg = gpr_eax + i;
- log->Printf("%12s = 0x%8.8" PRIx64, g_register_infos[reg].name, ((uint64_t*)&user.regs)[reg]);
- }
- }
-}
-
-bool
-RegisterContext_i386::ReadGPR()
-{
- bool result;
-
- ProcessMonitor &monitor = GetMonitor();
- result = monitor.ReadGPR(m_thread.GetID(), &user.regs, sizeof(user.regs));
- LogGPR("RegisterContext_i386::ReadGPR()");
- return result;
-}
-
-bool
-RegisterContext_i386::ReadFPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadFPR(m_thread.GetID(), &user.i387, sizeof(user.i387));
-}
diff --git a/source/Plugins/Process/POSIX/RegisterContext_i386.h b/source/Plugins/Process/POSIX/RegisterContext_i386.h
deleted file mode 100644
index 96066c47b815..000000000000
--- a/source/Plugins/Process/POSIX/RegisterContext_i386.h
+++ /dev/null
@@ -1,169 +0,0 @@
-//===-- RegisterContext_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_RegisterContext_i386_h_
-#define liblldb_RegisterContext_i386_h_
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/Log.h"
-#include "RegisterContextPOSIX.h"
-
-class RegisterContext_i386 : public RegisterContextPOSIX
-{
-public:
- RegisterContext_i386(lldb_private::Thread &thread,
- uint32_t concreate_frame_idx);
-
- ~RegisterContext_i386();
-
- void
- Invalidate();
-
- void
- InvalidateAllRegisters();
-
- size_t
- GetRegisterCount();
-
- const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(size_t reg);
-
- size_t
- GetRegisterSetCount();
-
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t set);
-
- unsigned
- GetRegisterIndexFromOffset(unsigned offset);
-
- const char *
- GetRegisterName(unsigned reg);
-
- bool
- ReadRegisterValue(uint32_t reg, lldb_private::Scalar &value);
-
- bool
- ReadRegisterBytes(uint32_t reg, lldb_private::DataExtractor &data);
-
- virtual bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value);
-
- 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);
-
- virtual bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value);
-
- 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];
- };
-
- // A user area like this no longer exists on FreeBSD
- // making this a Linux artifact. Nonetheless, it is safe
- // leaving it here while the code is being cleaned up and generalized.
-
- 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();
-
- void LogGPR(const char *title);
-
- bool ReadGPR();
- bool ReadFPR();
-};
-
-#endif // #ifndef liblldb_RegisterContext_i386_h_
diff --git a/source/Plugins/Process/POSIX/RegisterContext_mips64.h b/source/Plugins/Process/POSIX/RegisterContext_mips64.h
new file mode 100644
index 000000000000..dfd473d7cbec
--- /dev/null
+++ b/source/Plugins/Process/POSIX/RegisterContext_mips64.h
@@ -0,0 +1,104 @@
+//===-- RegisterContext_mips64.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_RegisterContext_mips64_H_
+#define liblldb_RegisterContext_mips64_H_
+
+// GCC and DWARF Register numbers (eRegisterKindGCC & eRegisterKindDWARF)
+enum
+{
+ // GP Registers
+ gcc_dwarf_zero_mips64 = 0,
+ gcc_dwarf_r1_mips64,
+ gcc_dwarf_r2_mips64,
+ gcc_dwarf_r3_mips64,
+ gcc_dwarf_r4_mips64,
+ gcc_dwarf_r5_mips64,
+ gcc_dwarf_r6_mips64,
+ gcc_dwarf_r7_mips64,
+ gcc_dwarf_r8_mips64,
+ gcc_dwarf_r9_mips64,
+ gcc_dwarf_r10_mips64,
+ gcc_dwarf_r11_mips64,
+ gcc_dwarf_r12_mips64,
+ gcc_dwarf_r13_mips64,
+ gcc_dwarf_r14_mips64,
+ gcc_dwarf_r15_mips64,
+ gcc_dwarf_r16_mips64,
+ gcc_dwarf_r17_mips64,
+ gcc_dwarf_r18_mips64,
+ gcc_dwarf_r19_mips64,
+ gcc_dwarf_r20_mips64,
+ gcc_dwarf_r21_mips64,
+ gcc_dwarf_r22_mips64,
+ gcc_dwarf_r23_mips64,
+ gcc_dwarf_r24_mips64,
+ gcc_dwarf_r25_mips64,
+ gcc_dwarf_r26_mips64,
+ gcc_dwarf_r27_mips64,
+ gcc_dwarf_gp_mips64,
+ gcc_dwarf_sp_mips64,
+ gcc_dwarf_r30_mips64,
+ gcc_dwarf_ra_mips64,
+ gcc_dwarf_sr_mips64,
+ gcc_dwarf_lo_mips64,
+ gcc_dwarf_hi_mips64,
+ gcc_dwarf_bad_mips64,
+ gcc_dwarf_cause_mips64,
+ gcc_dwarf_pc_mips64,
+ gcc_dwarf_ic_mips64,
+ gcc_dwarf_dummy_mips64
+};
+
+// GDB Register numbers (eRegisterKindGDB)
+enum
+{
+ gdb_zero_mips64 = 0,
+ gdb_r1_mips64,
+ gdb_r2_mips64,
+ gdb_r3_mips64,
+ gdb_r4_mips64,
+ gdb_r5_mips64,
+ gdb_r6_mips64,
+ gdb_r7_mips64,
+ gdb_r8_mips64,
+ gdb_r9_mips64,
+ gdb_r10_mips64,
+ gdb_r11_mips64,
+ gdb_r12_mips64,
+ gdb_r13_mips64,
+ gdb_r14_mips64,
+ gdb_r15_mips64,
+ gdb_r16_mips64,
+ gdb_r17_mips64,
+ gdb_r18_mips64,
+ gdb_r19_mips64,
+ gdb_r20_mips64,
+ gdb_r21_mips64,
+ gdb_r22_mips64,
+ gdb_r23_mips64,
+ gdb_r24_mips64,
+ gdb_r25_mips64,
+ gdb_r26_mips64,
+ gdb_r27_mips64,
+ gdb_gp_mips64,
+ gdb_sp_mips64,
+ gdb_r30_mips64,
+ gdb_ra_mips64,
+ gdb_sr_mips64,
+ gdb_lo_mips64,
+ gdb_hi_mips64,
+ gdb_bad_mips64,
+ gdb_cause_mips64,
+ gdb_pc_mips64,
+ gdb_ic_mips64,
+ gdb_dummy_mips64
+};
+
+#endif // liblldb_RegisterContext_mips64_H_
diff --git a/source/Plugins/Process/POSIX/RegisterContext_x86.h b/source/Plugins/Process/POSIX/RegisterContext_x86.h
index 61a25c407758..df3e1e5a84bf 100644
--- a/source/Plugins/Process/POSIX/RegisterContext_x86.h
+++ b/source/Plugins/Process/POSIX/RegisterContext_x86.h
@@ -1,4 +1,4 @@
-//===-- RegisterContext_x86.h ---------------------------*- C++ -*-===//
+//===-- RegisterContext_x86.h -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,101 +10,470 @@
#ifndef liblldb_RegisterContext_x86_H_
#define liblldb_RegisterContext_x86_H_
+//---------------------------------------------------------------------------
+// i386 gcc, dwarf, gdb enums
+//---------------------------------------------------------------------------
+
+// Register numbers seen in eh_frame (eRegisterKindGCC)
+//
+// From Jason Molenda: "gcc registers" is the register numbering used in the eh_frame
+// CFI. The only registers that are described in eh_frame CFI are those that are
+// preserved across function calls aka callee-saved aka non-volatile. And none
+// of the floating point registers on x86 are preserved across function calls.
+//
+// The only reason there is a "gcc register" and a "dwarf register" is because of a
+// mistake years and years ago with i386 where they got esp and ebp
+// backwards when they emitted the eh_frame instructions. Once there were
+// binaries In The Wild using the reversed numbering, we had to stick with it
+// forever.
+enum
+{
+ // 2nd parameter in DwarfRegNum() is regnum for exception handling on x86-32.
+ // See http://llvm.org/docs/WritingAnLLVMBackend.html#defining-a-register
+ gcc_eax_i386 = 0,
+ gcc_ecx_i386,
+ gcc_edx_i386,
+ gcc_ebx_i386,
+ gcc_ebp_i386, // Warning: these are switched from dwarf values
+ gcc_esp_i386, //
+ gcc_esi_i386,
+ gcc_edi_i386,
+ gcc_eip_i386,
+ gcc_eflags_i386,
+ gcc_st0_i386 = 12,
+ gcc_st1_i386,
+ gcc_st2_i386,
+ gcc_st3_i386,
+ gcc_st4_i386,
+ gcc_st5_i386,
+ gcc_st6_i386,
+ gcc_st7_i386,
+ gcc_xmm0_i386 = 21,
+ gcc_xmm1_i386,
+ gcc_xmm2_i386,
+ gcc_xmm3_i386,
+ gcc_xmm4_i386,
+ gcc_xmm5_i386,
+ gcc_xmm6_i386,
+ gcc_xmm7_i386,
+ gcc_mm0_i386 = 29,
+ gcc_mm1_i386,
+ gcc_mm2_i386,
+ gcc_mm3_i386,
+ gcc_mm4_i386,
+ gcc_mm5_i386,
+ gcc_mm6_i386,
+ gcc_mm7_i386,
+};
+
+// DWARF register numbers (eRegisterKindDWARF)
+// Intel's x86 or IA-32
enum
{
- gcc_eax = 0,
- gcc_ecx,
- gcc_edx,
- gcc_ebx,
- gcc_ebp,
- gcc_esp,
- gcc_esi,
- gcc_edi,
- gcc_eip,
- gcc_eflags
+ // General Purpose Registers.
+ dwarf_eax_i386 = 0,
+ dwarf_ecx_i386,
+ dwarf_edx_i386,
+ dwarf_ebx_i386,
+ dwarf_esp_i386,
+ dwarf_ebp_i386,
+ dwarf_esi_i386,
+ dwarf_edi_i386,
+ dwarf_eip_i386,
+ dwarf_eflags_i386,
+ // Floating Point Registers
+ dwarf_st0_i386 = 11,
+ dwarf_st1_i386,
+ dwarf_st2_i386,
+ dwarf_st3_i386,
+ dwarf_st4_i386,
+ dwarf_st5_i386,
+ dwarf_st6_i386,
+ dwarf_st7_i386,
+ // SSE Registers
+ dwarf_xmm0_i386 = 21,
+ dwarf_xmm1_i386,
+ dwarf_xmm2_i386,
+ dwarf_xmm3_i386,
+ dwarf_xmm4_i386,
+ dwarf_xmm5_i386,
+ dwarf_xmm6_i386,
+ dwarf_xmm7_i386,
+ // MMX Registers
+ dwarf_mm0_i386 = 29,
+ dwarf_mm1_i386,
+ dwarf_mm2_i386,
+ dwarf_mm3_i386,
+ dwarf_mm4_i386,
+ dwarf_mm5_i386,
+ dwarf_mm6_i386,
+ dwarf_mm7_i386,
+ dwarf_fctrl_i386 = 37, // x87 control word
+ dwarf_fstat_i386 = 38, // x87 status word
+ dwarf_mxcsr_i386 = 39,
+ dwarf_es_i386 = 40,
+ dwarf_cs_i386 = 41,
+ dwarf_ss_i386 = 42,
+ dwarf_ds_i386 = 43,
+ dwarf_fs_i386 = 44,
+ dwarf_gs_i386 = 45
+
+ // I believe the ymm registers use the dwarf_xmm%_i386 register numbers and
+ // then differentiate based on size of the register.
};
+// Register numbers GDB uses (eRegisterKindGDB)
+//
+// From Jason Molenda: The "gdb numbers" are what you would see in the stabs debug format.
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
+ gdb_eax_i386,
+ gdb_ecx_i386,
+ gdb_edx_i386,
+ gdb_ebx_i386,
+ gdb_esp_i386,
+ gdb_ebp_i386,
+ gdb_esi_i386,
+ gdb_edi_i386,
+ gdb_eip_i386,
+ gdb_eflags_i386,
+ gdb_cs_i386,
+ gdb_ss_i386,
+ gdb_ds_i386,
+ gdb_es_i386,
+ gdb_fs_i386,
+ gdb_gs_i386,
+ gdb_st0_i386 = 16,
+ gdb_st1_i386,
+ gdb_st2_i386,
+ gdb_st3_i386,
+ gdb_st4_i386,
+ gdb_st5_i386,
+ gdb_st6_i386,
+ gdb_st7_i386,
+ gdb_fctrl_i386, // FPU Control Word
+ gdb_fstat_i386, // FPU Status Word
+ gdb_ftag_i386, // FPU Tag Word
+ gdb_fiseg_i386, // FPU IP Selector
+ gdb_fioff_i386, // FPU IP Offset
+ gdb_foseg_i386, // FPU Operand Pointer Selector
+ gdb_fooff_i386, // FPU Operand Pointer Offset
+ gdb_fop_i386, // Last Instruction Opcode
+ gdb_xmm0_i386 = 32,
+ gdb_xmm1_i386,
+ gdb_xmm2_i386,
+ gdb_xmm3_i386,
+ gdb_xmm4_i386,
+ gdb_xmm5_i386,
+ gdb_xmm6_i386,
+ gdb_xmm7_i386,
+ gdb_mxcsr_i386 = 40,
+ gdb_ymm0h_i386,
+ gdb_ymm1h_i386,
+ gdb_ymm2h_i386,
+ gdb_ymm3h_i386,
+ gdb_ymm4h_i386,
+ gdb_ymm5h_i386,
+ gdb_ymm6h_i386,
+ gdb_ymm7h_i386,
+ gdb_mm0_i386,
+ gdb_mm1_i386,
+ gdb_mm2_i386,
+ gdb_mm3_i386,
+ gdb_mm4_i386,
+ gdb_mm5_i386,
+ gdb_mm6_i386,
+ gdb_mm7_i386,
};
+//---------------------------------------------------------------------------
+// AMD x86_64, AMD64, Intel EM64T, or Intel 64 gcc, dwarf, gdb enums
+//---------------------------------------------------------------------------
+
+// GCC and DWARF Register numbers (eRegisterKindGCC & eRegisterKindDWARF)
+// This is the spec I used (as opposed to x86-64-abi-0.99.pdf):
+// http://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf
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
+ // GP Registers
+ gcc_dwarf_rax_x86_64 = 0,
+ gcc_dwarf_rdx_x86_64,
+ gcc_dwarf_rcx_x86_64,
+ gcc_dwarf_rbx_x86_64,
+ gcc_dwarf_rsi_x86_64,
+ gcc_dwarf_rdi_x86_64,
+ gcc_dwarf_rbp_x86_64,
+ gcc_dwarf_rsp_x86_64,
+ // Extended GP Registers
+ gcc_dwarf_r8_x86_64 = 8,
+ gcc_dwarf_r9_x86_64,
+ gcc_dwarf_r10_x86_64,
+ gcc_dwarf_r11_x86_64,
+ gcc_dwarf_r12_x86_64,
+ gcc_dwarf_r13_x86_64,
+ gcc_dwarf_r14_x86_64,
+ gcc_dwarf_r15_x86_64,
+ // Return Address (RA) mapped to RIP
+ gcc_dwarf_rip_x86_64 = 16,
+ // SSE Vector Registers
+ gcc_dwarf_xmm0_x86_64 = 17,
+ gcc_dwarf_xmm1_x86_64,
+ gcc_dwarf_xmm2_x86_64,
+ gcc_dwarf_xmm3_x86_64,
+ gcc_dwarf_xmm4_x86_64,
+ gcc_dwarf_xmm5_x86_64,
+ gcc_dwarf_xmm6_x86_64,
+ gcc_dwarf_xmm7_x86_64,
+ gcc_dwarf_xmm8_x86_64,
+ gcc_dwarf_xmm9_x86_64,
+ gcc_dwarf_xmm10_x86_64,
+ gcc_dwarf_xmm11_x86_64,
+ gcc_dwarf_xmm12_x86_64,
+ gcc_dwarf_xmm13_x86_64,
+ gcc_dwarf_xmm14_x86_64,
+ gcc_dwarf_xmm15_x86_64,
+ // Floating Point Registers
+ gcc_dwarf_st0_x86_64 = 33,
+ gcc_dwarf_st1_x86_64,
+ gcc_dwarf_st2_x86_64,
+ gcc_dwarf_st3_x86_64,
+ gcc_dwarf_st4_x86_64,
+ gcc_dwarf_st5_x86_64,
+ gcc_dwarf_st6_x86_64,
+ gcc_dwarf_st7_x86_64,
+ // MMX Registers
+ gcc_dwarf_mm0_x86_64 = 41,
+ gcc_dwarf_mm1_x86_64,
+ gcc_dwarf_mm2_x86_64,
+ gcc_dwarf_mm3_x86_64,
+ gcc_dwarf_mm4_x86_64,
+ gcc_dwarf_mm5_x86_64,
+ gcc_dwarf_mm6_x86_64,
+ gcc_dwarf_mm7_x86_64,
+ // Control and Status Flags Register
+ gcc_dwarf_rflags_x86_64 = 49,
+ // selector registers
+ gcc_dwarf_es_x86_64 = 50,
+ gcc_dwarf_cs_x86_64,
+ gcc_dwarf_ss_x86_64,
+ gcc_dwarf_ds_x86_64,
+ gcc_dwarf_fs_x86_64,
+ gcc_dwarf_gs_x86_64,
+ // Floating point control registers
+ gcc_dwarf_mxcsr_x86_64 = 64, // Media Control and Status
+ gcc_dwarf_fctrl_x86_64, // x87 control word
+ gcc_dwarf_fstat_x86_64, // x87 status word
+ // Upper Vector Registers
+ gcc_dwarf_ymm0h_x86_64 = 67,
+ gcc_dwarf_ymm1h_x86_64,
+ gcc_dwarf_ymm2h_x86_64,
+ gcc_dwarf_ymm3h_x86_64,
+ gcc_dwarf_ymm4h_x86_64,
+ gcc_dwarf_ymm5h_x86_64,
+ gcc_dwarf_ymm6h_x86_64,
+ gcc_dwarf_ymm7h_x86_64,
+ gcc_dwarf_ymm8h_x86_64,
+ gcc_dwarf_ymm9h_x86_64,
+ gcc_dwarf_ymm10h_x86_64,
+ gcc_dwarf_ymm11h_x86_64,
+ gcc_dwarf_ymm12h_x86_64,
+ gcc_dwarf_ymm13h_x86_64,
+ gcc_dwarf_ymm14h_x86_64,
+ gcc_dwarf_ymm15h_x86_64,
+ // AVX2 Vector Mask Registers
+ // gcc_dwarf_k0_x86_64 = 118,
+ // gcc_dwarf_k1_x86_64,
+ // gcc_dwarf_k2_x86_64,
+ // gcc_dwarf_k3_x86_64,
+ // gcc_dwarf_k4_x86_64,
+ // gcc_dwarf_k5_x86_64,
+ // gcc_dwarf_k6_x86_64,
+ // gcc_dwarf_k7_x86_64,
+};
+
+// GDB Register numbers (eRegisterKindGDB)
+enum
+{
+ // GP Registers
+ gdb_rax_x86_64 = 0,
+ gdb_rbx_x86_64,
+ gdb_rcx_x86_64,
+ gdb_rdx_x86_64,
+ gdb_rsi_x86_64,
+ gdb_rdi_x86_64,
+ gdb_rbp_x86_64,
+ gdb_rsp_x86_64,
+ // Extended GP Registers
+ gdb_r8_x86_64,
+ gdb_r9_x86_64,
+ gdb_r10_x86_64,
+ gdb_r11_x86_64,
+ gdb_r12_x86_64,
+ gdb_r13_x86_64,
+ gdb_r14_x86_64,
+ gdb_r15_x86_64,
+ // Return Address (RA) mapped to RIP
+ gdb_rip_x86_64,
+ // Control and Status Flags Register
+ gdb_rflags_x86_64,
+ gdb_cs_x86_64,
+ gdb_ss_x86_64,
+ gdb_ds_x86_64,
+ gdb_es_x86_64,
+ gdb_fs_x86_64,
+ gdb_gs_x86_64,
+ // Floating Point Registers
+ gdb_st0_x86_64,
+ gdb_st1_x86_64,
+ gdb_st2_x86_64,
+ gdb_st3_x86_64,
+ gdb_st4_x86_64,
+ gdb_st5_x86_64,
+ gdb_st6_x86_64,
+ gdb_st7_x86_64,
+ gdb_fctrl_x86_64,
+ gdb_fstat_x86_64,
+ gdb_ftag_x86_64,
+ gdb_fiseg_x86_64,
+ gdb_fioff_x86_64,
+ gdb_foseg_x86_64,
+ gdb_fooff_x86_64,
+ gdb_fop_x86_64,
+ // SSE Vector Registers
+ gdb_xmm0_x86_64 = 40,
+ gdb_xmm1_x86_64,
+ gdb_xmm2_x86_64,
+ gdb_xmm3_x86_64,
+ gdb_xmm4_x86_64,
+ gdb_xmm5_x86_64,
+ gdb_xmm6_x86_64,
+ gdb_xmm7_x86_64,
+ gdb_xmm8_x86_64,
+ gdb_xmm9_x86_64,
+ gdb_xmm10_x86_64,
+ gdb_xmm11_x86_64,
+ gdb_xmm12_x86_64,
+ gdb_xmm13_x86_64,
+ gdb_xmm14_x86_64,
+ gdb_xmm15_x86_64,
+ // Floating point control registers
+ gdb_mxcsr_x86_64 = 56,
+ gdb_ymm0h_x86_64,
+ gdb_ymm1h_x86_64,
+ gdb_ymm2h_x86_64,
+ gdb_ymm3h_x86_64,
+ gdb_ymm4h_x86_64,
+ gdb_ymm5h_x86_64,
+ gdb_ymm6h_x86_64,
+ gdb_ymm7h_x86_64,
+ gdb_ymm8h_x86_64,
+ gdb_ymm9h_x86_64,
+ gdb_ymm10h_x86_64,
+ gdb_ymm11h_x86_64,
+ gdb_ymm12h_x86_64,
+ gdb_ymm13h_x86_64,
+ gdb_ymm14h_x86_64,
+ gdb_ymm15h_x86_64
+};
+
+//---------------------------------------------------------------------------
+// Generic floating-point registers
+//---------------------------------------------------------------------------
+
+struct MMSReg
+{
+ uint8_t bytes[10];
+ uint8_t pad[6];
+};
+
+struct XMMReg
+{
+ uint8_t bytes[16]; // 128-bits for each XMM register
+};
+
+// i387_fxsave_struct
+struct FXSAVE
+{
+ uint16_t fctrl; // FPU Control Word (fcw)
+ uint16_t fstat; // FPU Status Word (fsw)
+ uint16_t ftag; // FPU Tag Word (ftw)
+ uint16_t fop; // Last Instruction Opcode (fop)
+ union
+ {
+ struct
+ {
+ uint64_t fip; // Instruction Pointer
+ uint64_t fdp; // Data Pointer
+ } x86_64;
+ struct
+ {
+ uint32_t fioff; // FPU IP Offset (fip)
+ uint32_t fiseg; // FPU IP Selector (fcs)
+ uint32_t fooff; // FPU Operand Pointer Offset (foo)
+ uint32_t foseg; // FPU Operand Pointer Selector (fos)
+ } i386;
+ } ptr;
+ uint32_t mxcsr; // MXCSR Register State
+ uint32_t mxcsrmask; // MXCSR Mask
+ MMSReg stmm[8]; // 8*16 bytes for each FP-reg = 128 bytes
+ XMMReg xmm[16]; // 16*16 bytes for each XMM-reg = 256 bytes
+ uint32_t padding[24];
+};
+
+//---------------------------------------------------------------------------
+// Extended floating-point registers
+//---------------------------------------------------------------------------
+
+struct YMMHReg
+{
+ uint8_t bytes[16]; // 16 * 8 bits for the high bytes of each YMM register
+};
+
+struct YMMReg
+{
+ uint8_t bytes[32]; // 16 * 16 bits for each YMM register
+};
+
+struct YMM
+{
+ YMMReg ymm[16]; // assembled from ymmh and xmm registers
+};
+
+struct XSAVE_HDR
+{
+ uint64_t xstate_bv; // OS enabled xstate mask to determine the extended states supported by the processor
+ uint64_t reserved1[2];
+ uint64_t reserved2[5];
+} __attribute__((packed));
+
+// x86 extensions to FXSAVE (i.e. for AVX processors)
+struct XSAVE
+{
+ FXSAVE i387; // floating point registers typical in i387_fxsave_struct
+ XSAVE_HDR header; // The xsave_hdr_struct can be used to determine if the following extensions are usable
+ YMMHReg ymmh[16]; // High 16 bytes of each of 16 YMM registers (the low bytes are in FXSAVE.xmm for compatibility with SSE)
+ // Slot any extensions to the register file here
+} __attribute__((packed, aligned (64)));
+
+// Floating-point registers
+struct FPR
+{
+ // Thread state for the floating-point unit of the processor read by ptrace.
+ union XSTATE
+ {
+ FXSAVE fxsave; // Generic floating-point registers.
+ XSAVE xsave; // x86 extended processor state.
+ } xstate;
+};
+
+//---------------------------------------------------------------------------
+// ptrace PTRACE_GETREGSET, PTRACE_SETREGSET structure
+//---------------------------------------------------------------------------
+
+struct IOVEC
+{
+ void *iov_base; // pointer to XSAVE
+ size_t iov_len; // sizeof(XSAVE)
};
#endif
diff --git a/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp b/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp
deleted file mode 100644
index 617b18484e5a..000000000000
--- a/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp
+++ /dev/null
@@ -1,1563 +0,0 @@
-//===-- RegisterContext_x86_64.cpp -------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include <cstring>
-#include <errno.h>
-#include <stdint.h>
-
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/Scalar.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Host/Endian.h"
-#include "llvm/Support/Compiler.h"
-
-#include "ProcessPOSIX.h"
-#if defined(__linux__) or defined(__FreeBSD__)
-#include "ProcessMonitor.h"
-#endif
-#include "RegisterContext_i386.h"
-#include "RegisterContext_x86.h"
-#include "RegisterContext_x86_64.h"
-#include "Plugins/Process/elf-core/ProcessElfCore.h"
-
-using namespace lldb_private;
-using namespace lldb;
-
-// Support ptrace extensions even when compiled without required kernel support
-#ifndef NT_X86_XSTATE
- #define NT_X86_XSTATE 0x202
-#endif
-
-enum
-{
- gcc_dwarf_gpr_rax = 0,
- gcc_dwarf_gpr_rdx,
- gcc_dwarf_gpr_rcx,
- gcc_dwarf_gpr_rbx,
- gcc_dwarf_gpr_rsi,
- gcc_dwarf_gpr_rdi,
- gcc_dwarf_gpr_rbp,
- gcc_dwarf_gpr_rsp,
- gcc_dwarf_gpr_r8,
- gcc_dwarf_gpr_r9,
- gcc_dwarf_gpr_r10,
- gcc_dwarf_gpr_r11,
- gcc_dwarf_gpr_r12,
- gcc_dwarf_gpr_r13,
- gcc_dwarf_gpr_r14,
- gcc_dwarf_gpr_r15,
- gcc_dwarf_gpr_rip,
- gcc_dwarf_fpu_xmm0,
- gcc_dwarf_fpu_xmm1,
- gcc_dwarf_fpu_xmm2,
- gcc_dwarf_fpu_xmm3,
- gcc_dwarf_fpu_xmm4,
- gcc_dwarf_fpu_xmm5,
- gcc_dwarf_fpu_xmm6,
- gcc_dwarf_fpu_xmm7,
- gcc_dwarf_fpu_xmm8,
- gcc_dwarf_fpu_xmm9,
- gcc_dwarf_fpu_xmm10,
- gcc_dwarf_fpu_xmm11,
- gcc_dwarf_fpu_xmm12,
- gcc_dwarf_fpu_xmm13,
- gcc_dwarf_fpu_xmm14,
- gcc_dwarf_fpu_xmm15,
- gcc_dwarf_fpu_stmm0,
- gcc_dwarf_fpu_stmm1,
- gcc_dwarf_fpu_stmm2,
- gcc_dwarf_fpu_stmm3,
- gcc_dwarf_fpu_stmm4,
- gcc_dwarf_fpu_stmm5,
- gcc_dwarf_fpu_stmm6,
- gcc_dwarf_fpu_stmm7,
- gcc_dwarf_fpu_ymm0,
- gcc_dwarf_fpu_ymm1,
- gcc_dwarf_fpu_ymm2,
- gcc_dwarf_fpu_ymm3,
- gcc_dwarf_fpu_ymm4,
- gcc_dwarf_fpu_ymm5,
- gcc_dwarf_fpu_ymm6,
- gcc_dwarf_fpu_ymm7,
- gcc_dwarf_fpu_ymm8,
- gcc_dwarf_fpu_ymm9,
- gcc_dwarf_fpu_ymm10,
- gcc_dwarf_fpu_ymm11,
- gcc_dwarf_fpu_ymm12,
- gcc_dwarf_fpu_ymm13,
- gcc_dwarf_fpu_ymm14,
- gcc_dwarf_fpu_ymm15
-};
-
-enum
-{
- gdb_gpr_rax = 0,
- gdb_gpr_rbx = 1,
- gdb_gpr_rcx = 2,
- gdb_gpr_rdx = 3,
- gdb_gpr_rsi = 4,
- gdb_gpr_rdi = 5,
- gdb_gpr_rbp = 6,
- gdb_gpr_rsp = 7,
- gdb_gpr_r8 = 8,
- gdb_gpr_r9 = 9,
- gdb_gpr_r10 = 10,
- gdb_gpr_r11 = 11,
- gdb_gpr_r12 = 12,
- gdb_gpr_r13 = 13,
- gdb_gpr_r14 = 14,
- gdb_gpr_r15 = 15,
- gdb_gpr_rip = 16,
- gdb_gpr_rflags = 17,
- gdb_gpr_cs = 18,
- gdb_gpr_ss = 19,
- gdb_gpr_ds = 20,
- gdb_gpr_es = 21,
- gdb_gpr_fs = 22,
- gdb_gpr_gs = 23,
- gdb_fpu_stmm0 = 24,
- gdb_fpu_stmm1 = 25,
- gdb_fpu_stmm2 = 26,
- gdb_fpu_stmm3 = 27,
- gdb_fpu_stmm4 = 28,
- gdb_fpu_stmm5 = 29,
- gdb_fpu_stmm6 = 30,
- gdb_fpu_stmm7 = 31,
- gdb_fpu_fcw = 32,
- gdb_fpu_fsw = 33,
- gdb_fpu_ftw = 34,
- gdb_fpu_cs_64 = 35,
- gdb_fpu_ip = 36,
- gdb_fpu_ds_64 = 37,
- gdb_fpu_dp = 38,
- gdb_fpu_fop = 39,
- gdb_fpu_xmm0 = 40,
- gdb_fpu_xmm1 = 41,
- gdb_fpu_xmm2 = 42,
- gdb_fpu_xmm3 = 43,
- gdb_fpu_xmm4 = 44,
- gdb_fpu_xmm5 = 45,
- gdb_fpu_xmm6 = 46,
- gdb_fpu_xmm7 = 47,
- gdb_fpu_xmm8 = 48,
- gdb_fpu_xmm9 = 49,
- gdb_fpu_xmm10 = 50,
- gdb_fpu_xmm11 = 51,
- gdb_fpu_xmm12 = 52,
- gdb_fpu_xmm13 = 53,
- gdb_fpu_xmm14 = 54,
- gdb_fpu_xmm15 = 55,
- gdb_fpu_mxcsr = 56,
- gdb_fpu_ymm0 = 57,
- gdb_fpu_ymm1 = 58,
- gdb_fpu_ymm2 = 59,
- gdb_fpu_ymm3 = 60,
- gdb_fpu_ymm4 = 61,
- gdb_fpu_ymm5 = 62,
- gdb_fpu_ymm6 = 63,
- gdb_fpu_ymm7 = 64,
- gdb_fpu_ymm8 = 65,
- gdb_fpu_ymm9 = 66,
- gdb_fpu_ymm10 = 67,
- gdb_fpu_ymm11 = 68,
- gdb_fpu_ymm12 = 69,
- gdb_fpu_ymm13 = 70,
- gdb_fpu_ymm14 = 71,
- gdb_fpu_ymm15 = 72
-};
-
-static const
-uint32_t g_gpr_regnums[k_num_gpr_registers] =
-{
- gpr_rax,
- 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
-};
-
-static const uint32_t
-g_fpu_regnums[k_num_fpr_registers] =
-{
- fpu_fcw,
- 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
-};
-
-static const uint32_t
-g_avx_regnums[k_num_avx_registers] =
-{
- fpu_ymm0,
- 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
-};
-
-// Number of register sets provided by this context.
-enum
-{
- k_num_extended_register_sets = 1,
- k_num_register_sets = 3
-};
-
-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_fpr_registers, g_fpu_regnums },
- { "Advanced Vector Extensions", "avx", k_num_avx_registers, g_avx_regnums }
-};
-
-// Computes the offset of the given FPR in the extended data area.
-#define FPR_OFFSET(regname) \
- (offsetof(RegisterContext_x86_64::FPR, xstate) + \
- offsetof(RegisterContext_x86_64::FXSAVE, regname))
-
-// Computes the offset of the YMM register assembled from register halves.
-#define YMM_OFFSET(regname) \
- (offsetof(RegisterContext_x86_64::YMM, regname))
-
-// Number of bytes needed to represent a i386 GPR
-#define GPR_i386_SIZE(reg) sizeof(((RegisterContext_i386::GPR*)NULL)->reg)
-
-// Number of bytes needed to represent a FPR.
-#define FPR_SIZE(reg) sizeof(((RegisterContext_x86_64::FXSAVE*)NULL)->reg)
-
-// Number of bytes needed to represent the i'th FP register.
-#define FP_SIZE sizeof(((RegisterContext_x86_64::MMSReg*)NULL)->bytes)
-
-// Number of bytes needed to represent an XMM register.
-#define XMM_SIZE sizeof(RegisterContext_x86_64::XMMReg)
-
-// Number of bytes needed to represent a YMM register.
-#define YMM_SIZE sizeof(RegisterContext_x86_64::YMMReg)
-
-// 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 }
-
-// Dummy data for RegisterInfo::value_regs as expected by DumpRegisterSet.
-static uint32_t value_regs = LLDB_INVALID_REGNUM;
-
-#define DEFINE_GPR_i386(reg_i386, reg_x86_64, alt, kind1, kind2, kind3, kind4) \
- { #reg_i386, alt, GPR_i386_SIZE(reg_i386), 0, eEncodingUint, \
- eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg_i386 }, &value_regs, NULL }
-
-#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) \
- { #reg#i, NULL, FP_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { gcc_dwarf_fpu_##reg##i, gcc_dwarf_fpu_##reg##i, \
- LLDB_INVALID_REGNUM, gdb_fpu_##reg##i, fpu_##reg##i }, NULL, NULL }
-
-#define DEFINE_XMM(reg, i) \
- { #reg#i, NULL, XMM_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { 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) \
- { #reg#i, NULL, YMM_SIZE, LLVM_EXTENSION YMM_OFFSET(reg[i]), \
- eEncodingVector, eFormatVectorOfUInt8, \
- { gcc_dwarf_fpu_##reg##i, gcc_dwarf_fpu_##reg##i, \
- LLDB_INVALID_REGNUM, gdb_fpu_##reg##i, fpu_##reg##i }, NULL, NULL }
-
-#define DEFINE_DR(reg, i) \
- { #reg#i, NULL, 0, 0, eEncodingUint, eFormatHex, \
- { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
- LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL }
-
-#define REG_CONTEXT_SIZE (GetGPRSize() + sizeof(RegisterContext_x86_64::FPR))
-
-static RegisterInfo
-g_register_infos[k_num_registers] =
-{
- // General purpose registers.
- DEFINE_GPR(rax, NULL, gcc_dwarf_gpr_rax, gcc_dwarf_gpr_rax, LLDB_INVALID_REGNUM, gdb_gpr_rax),
- DEFINE_GPR(rbx, NULL, gcc_dwarf_gpr_rbx, gcc_dwarf_gpr_rbx, LLDB_INVALID_REGNUM, gdb_gpr_rbx),
- DEFINE_GPR(rcx, NULL, gcc_dwarf_gpr_rcx, gcc_dwarf_gpr_rcx, LLDB_INVALID_REGNUM, gdb_gpr_rcx),
- DEFINE_GPR(rdx, NULL, gcc_dwarf_gpr_rdx, gcc_dwarf_gpr_rdx, LLDB_INVALID_REGNUM, gdb_gpr_rdx),
- DEFINE_GPR(rdi, NULL, gcc_dwarf_gpr_rdi, gcc_dwarf_gpr_rdi, LLDB_INVALID_REGNUM, gdb_gpr_rdi),
- DEFINE_GPR(rsi, NULL, gcc_dwarf_gpr_rsi, gcc_dwarf_gpr_rsi, LLDB_INVALID_REGNUM, gdb_gpr_rsi),
- DEFINE_GPR(rbp, "fp", gcc_dwarf_gpr_rbp, gcc_dwarf_gpr_rbp, LLDB_REGNUM_GENERIC_FP, gdb_gpr_rbp),
- DEFINE_GPR(rsp, "sp", gcc_dwarf_gpr_rsp, gcc_dwarf_gpr_rsp, LLDB_REGNUM_GENERIC_SP, gdb_gpr_rsp),
- DEFINE_GPR(r8, NULL, gcc_dwarf_gpr_r8, gcc_dwarf_gpr_r8, LLDB_INVALID_REGNUM, gdb_gpr_r8),
- DEFINE_GPR(r9, NULL, gcc_dwarf_gpr_r9, gcc_dwarf_gpr_r9, LLDB_INVALID_REGNUM, gdb_gpr_r9),
- DEFINE_GPR(r10, NULL, gcc_dwarf_gpr_r10, gcc_dwarf_gpr_r10, LLDB_INVALID_REGNUM, gdb_gpr_r10),
- DEFINE_GPR(r11, NULL, gcc_dwarf_gpr_r11, gcc_dwarf_gpr_r11, LLDB_INVALID_REGNUM, gdb_gpr_r11),
- DEFINE_GPR(r12, NULL, gcc_dwarf_gpr_r12, gcc_dwarf_gpr_r12, LLDB_INVALID_REGNUM, gdb_gpr_r12),
- DEFINE_GPR(r13, NULL, gcc_dwarf_gpr_r13, gcc_dwarf_gpr_r13, LLDB_INVALID_REGNUM, gdb_gpr_r13),
- DEFINE_GPR(r14, NULL, gcc_dwarf_gpr_r14, gcc_dwarf_gpr_r14, LLDB_INVALID_REGNUM, gdb_gpr_r14),
- DEFINE_GPR(r15, NULL, gcc_dwarf_gpr_r15, gcc_dwarf_gpr_r15, LLDB_INVALID_REGNUM, gdb_gpr_r15),
- DEFINE_GPR(rip, "pc", gcc_dwarf_gpr_rip, gcc_dwarf_gpr_rip, LLDB_REGNUM_GENERIC_PC, gdb_gpr_rip),
- DEFINE_GPR(rflags, "flags", LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, gdb_gpr_rflags),
- DEFINE_GPR(cs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_cs),
- DEFINE_GPR(fs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_fs),
- DEFINE_GPR(gs, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_gs),
- DEFINE_GPR(ss, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_ss),
- DEFINE_GPR(ds, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_ds),
- DEFINE_GPR(es, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_es),
- // i386 registers
- DEFINE_GPR_i386(eax, rax, NULL, gcc_eax, dwarf_eax, LLDB_INVALID_REGNUM, gdb_eax),
- DEFINE_GPR_i386(ebx, rbx, NULL, gcc_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, gdb_ebx),
- DEFINE_GPR_i386(ecx, rcx, NULL, gcc_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, gdb_ecx),
- DEFINE_GPR_i386(edx, rdx, NULL, gcc_edx, dwarf_edx, LLDB_INVALID_REGNUM, gdb_edx),
- DEFINE_GPR_i386(edi, rdi, NULL, gcc_edi, dwarf_edi, LLDB_INVALID_REGNUM, gdb_edi),
- DEFINE_GPR_i386(esi, rsi, NULL, gcc_esi, dwarf_esi, LLDB_INVALID_REGNUM, gdb_esi),
- DEFINE_GPR_i386(ebp, rbp, "fp", gcc_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, gdb_ebp),
- DEFINE_GPR_i386(esp, rsp, "sp", gcc_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, gdb_esp),
- DEFINE_GPR_i386(eip, rip, "pc", gcc_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, gdb_eip),
- DEFINE_GPR_i386(eflags, rflags, "flags", gcc_eflags, dwarf_eflags, LLDB_REGNUM_GENERIC_FLAGS, gdb_eflags),
- // i387 Floating point registers.
- DEFINE_FPR(fcw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fcw),
- DEFINE_FPR(fsw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fsw),
- DEFINE_FPR(ftw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ftw),
- DEFINE_FPR(fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fop),
- DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ip),
- // FIXME: Extract segment from ip.
- DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_cs_64),
- DEFINE_FPR(dp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_dp),
- // FIXME: Extract segment from dp.
- DEFINE_FPR(dp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ds_64),
- DEFINE_FPR(mxcsr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_mxcsr),
- DEFINE_FPR(mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
-
- // FP registers.
- 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),
- DEFINE_XMM(xmm, 8),
- DEFINE_XMM(xmm, 9),
- DEFINE_XMM(xmm, 10),
- DEFINE_XMM(xmm, 11),
- DEFINE_XMM(xmm, 12),
- DEFINE_XMM(xmm, 13),
- DEFINE_XMM(xmm, 14),
- DEFINE_XMM(xmm, 15),
-
- // Copy of YMM registers assembled from xmm and ymmh
- DEFINE_YMM(ymm, 0),
- DEFINE_YMM(ymm, 1),
- DEFINE_YMM(ymm, 2),
- DEFINE_YMM(ymm, 3),
- DEFINE_YMM(ymm, 4),
- DEFINE_YMM(ymm, 5),
- DEFINE_YMM(ymm, 6),
- DEFINE_YMM(ymm, 7),
- DEFINE_YMM(ymm, 8),
- DEFINE_YMM(ymm, 9),
- DEFINE_YMM(ymm, 10),
- DEFINE_YMM(ymm, 11),
- DEFINE_YMM(ymm, 12),
- DEFINE_YMM(ymm, 13),
- DEFINE_YMM(ymm, 14),
- DEFINE_YMM(ymm, 15),
-
- // Debug registers for lldb internal use
- DEFINE_DR(dr, 0),
- DEFINE_DR(dr, 1),
- DEFINE_DR(dr, 2),
- DEFINE_DR(dr, 3),
- DEFINE_DR(dr, 4),
- DEFINE_DR(dr, 5),
- DEFINE_DR(dr, 6),
- DEFINE_DR(dr, 7)
-};
-
-static bool IsGPR(unsigned reg)
-{
- return reg <= k_last_gpr; // GPR's come first.
-}
-
-static bool IsAVX(unsigned reg)
-{
- return (k_first_avx <= reg && reg <= k_last_avx);
-}
-static bool IsFPR(unsigned reg)
-{
- return (k_first_fpr <= reg && reg <= k_last_fpr);
-}
-
-
-bool RegisterContext_x86_64::IsFPR(unsigned reg, FPRType fpr_type)
-{
- bool generic_fpr = ::IsFPR(reg);
- if (fpr_type == eXSAVE)
- return generic_fpr || IsAVX(reg);
-
- return generic_fpr;
-}
-
-RegisterContext_x86_64::RegisterContext_x86_64(Thread &thread,
- uint32_t concrete_frame_idx)
- : RegisterContextPOSIX(thread, concrete_frame_idx)
-{
- // Initialize m_iovec to point to the buffer and buffer size
- // using the conventions of Berkeley style UIO structures, as required
- // by PTRACE extensions.
- m_iovec.iov_base = &m_fpr.xstate.xsave;
- m_iovec.iov_len = sizeof(m_fpr.xstate.xsave);
-
- ::memset(&m_fpr, 0, sizeof(RegisterContext_x86_64::FPR));
-
- // elf-core yet to support ReadFPR()
- ProcessSP base = CalculateProcess();
- if (base.get()->GetPluginName() == ProcessElfCore::GetPluginNameStatic())
- return;
-
- // TODO: Use assembly to call cpuid on the inferior and query ebx or ecx
- m_fpr_type = eXSAVE; // extended floating-point registers, if available
- if (false == ReadFPR())
- m_fpr_type = eFXSAVE; // assume generic floating-point registers
-}
-
-RegisterContext_x86_64::~RegisterContext_x86_64()
-{
-}
-
-void
-RegisterContext_x86_64::Invalidate()
-{
-}
-
-void
-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()
-{
- size_t num_registers = k_num_gpr_registers + k_num_fpr_registers;
- if (m_fpr_type == eXSAVE)
- return num_registers + k_num_avx_registers;
- return num_registers;
-}
-
-const RegisterInfo *
-RegisterContext_x86_64::GetRegisterInfo()
-{
- // Commonly, this method is overridden and g_register_infos is copied and specialized.
- // So, use GetRegisterInfo() rather than g_register_infos in this scope.
- return g_register_infos;
-}
-
-const RegisterInfo *
-RegisterContext_x86_64::GetRegisterInfoAtIndex(size_t reg)
-{
- if (reg < k_num_registers)
- return &GetRegisterInfo()[reg];
- else
- return NULL;
-}
-
-size_t
-RegisterContext_x86_64::GetRegisterSetCount()
-{
- size_t sets = 0;
- for (size_t set = 0; set < k_num_register_sets; ++set)
- if (IsRegisterSetAvailable(set))
- ++sets;
-
- return sets;
-}
-
-const RegisterSet *
-RegisterContext_x86_64::GetRegisterSet(size_t set)
-{
- if (IsRegisterSetAvailable(set))
- return &g_reg_sets[set];
- else
- return NULL;
-}
-
-unsigned
-RegisterContext_x86_64::GetRegisterIndexFromOffset(unsigned offset)
-{
- unsigned reg;
- for (reg = 0; reg < k_num_registers; reg++)
- {
- if (GetRegisterInfo()[reg].byte_offset == offset)
- break;
- }
- assert(reg < k_num_registers && "Invalid register offset.");
- return reg;
-}
-
-const char *
-RegisterContext_x86_64::GetRegisterName(unsigned reg)
-{
- assert(reg < k_num_registers && "Invalid register offset.");
- return GetRegisterInfo()[reg].name;
-}
-
-lldb::ByteOrder
-RegisterContext_x86_64::GetByteOrder()
-{
- // Get the target process whose privileged thread was used for the register read.
- lldb::ByteOrder byte_order = eByteOrderInvalid;
- Process *process = CalculateProcess().get();
-
- if (process)
- byte_order = process->GetByteOrder();
- return byte_order;
-}
-
-// Parse ymm registers and into xmm.bytes and ymmh.bytes.
-bool RegisterContext_x86_64::CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order)
-{
- if (!IsAVX(reg))
- return false;
-
- if (byte_order == eByteOrderLittle) {
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - fpu_ymm0].bytes,
- m_ymm_set.ymm[reg - fpu_ymm0].bytes,
- sizeof(RegisterContext_x86_64::XMMReg));
- ::memcpy(m_fpr.xstate.xsave.ymmh[reg - fpu_ymm0].bytes,
- m_ymm_set.ymm[reg - fpu_ymm0].bytes + sizeof(RegisterContext_x86_64::XMMReg),
- sizeof(RegisterContext_x86_64::YMMHReg));
- return true;
- }
-
- if (byte_order == eByteOrderBig) {
- ::memcpy(m_fpr.xstate.fxsave.xmm[reg - fpu_ymm0].bytes,
- m_ymm_set.ymm[reg - fpu_ymm0].bytes + sizeof(RegisterContext_x86_64::XMMReg),
- sizeof(RegisterContext_x86_64::XMMReg));
- ::memcpy(m_fpr.xstate.xsave.ymmh[reg - fpu_ymm0].bytes,
- m_ymm_set.ymm[reg - fpu_ymm0].bytes,
- sizeof(RegisterContext_x86_64::YMMHReg));
- return true;
- }
- return false; // unsupported or invalid byte order
-}
-
-// Concatenate xmm.bytes with ymmh.bytes
-bool RegisterContext_x86_64::CopyXSTATEtoYMM(uint32_t reg, lldb::ByteOrder byte_order)
-{
- if (!IsAVX(reg))
- return false;
-
- if (byte_order == eByteOrderLittle) {
- ::memcpy(m_ymm_set.ymm[reg - fpu_ymm0].bytes,
- m_fpr.xstate.fxsave.xmm[reg - fpu_ymm0].bytes,
- sizeof(RegisterContext_x86_64::XMMReg));
- ::memcpy(m_ymm_set.ymm[reg - fpu_ymm0].bytes + sizeof(RegisterContext_x86_64::XMMReg),
- m_fpr.xstate.xsave.ymmh[reg - fpu_ymm0].bytes,
- sizeof(RegisterContext_x86_64::YMMHReg));
- return true;
- }
- if (byte_order == eByteOrderBig) {
- ::memcpy(m_ymm_set.ymm[reg - fpu_ymm0].bytes + sizeof(RegisterContext_x86_64::XMMReg),
- m_fpr.xstate.fxsave.xmm[reg - fpu_ymm0].bytes,
- sizeof(RegisterContext_x86_64::XMMReg));
- ::memcpy(m_ymm_set.ymm[reg - fpu_ymm0].bytes,
- m_fpr.xstate.xsave.ymmh[reg - fpu_ymm0].bytes,
- sizeof(RegisterContext_x86_64::YMMHReg));
- return true;
- }
- return false; // unsupported or invalid byte order
-}
-
-bool
-RegisterContext_x86_64::IsRegisterSetAvailable(size_t set_index)
-{
- // Note: Extended register sets are assumed to be at the end of g_reg_sets...
- size_t num_sets = k_num_register_sets - k_num_extended_register_sets;
- if (m_fpr_type == eXSAVE) // ...and to start with AVX registers.
- ++num_sets;
-
- return (set_index < num_sets);
-}
-
-bool
-RegisterContext_x86_64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
-{
- if (!reg_info)
- return false;
-
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
-
- if (IsFPR(reg, m_fpr_type)) {
- if (!ReadFPR())
- return false;
- }
- else {
- bool success = ReadRegister(reg, value);
-
- // If an i386 register should be parsed from an x86_64 register...
- if (success && reg >= k_first_i386 && reg <= k_last_i386)
- if (value.GetByteSize() > reg_info->byte_size)
- value.SetType(reg_info); // ...use the type specified by reg_info rather than the uint64_t default
- return success;
- }
-
- if (reg_info->encoding == eEncodingVector) {
- ByteOrder byte_order = GetByteOrder();
-
- if (byte_order != ByteOrder::eByteOrderInvalid) {
- if (reg >= fpu_stmm0 && reg <= fpu_stmm7) {
- value.SetBytes(m_fpr.xstate.fxsave.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size, byte_order);
- }
- if (reg >= fpu_xmm0 && reg <= fpu_xmm15) {
- value.SetBytes(m_fpr.xstate.fxsave.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size, byte_order);
- }
- if (reg >= fpu_ymm0 && reg <= fpu_ymm15) {
- // Concatenate ymm using the register halves in xmm.bytes and ymmh.bytes
- if (m_fpr_type == eXSAVE && CopyXSTATEtoYMM(reg, byte_order))
- value.SetBytes(m_ymm_set.ymm[reg - fpu_ymm0].bytes, reg_info->byte_size, byte_order);
- else
- return false;
- }
- return value.GetType() == RegisterValue::eTypeBytes;
- }
- return false;
- }
-
- // Note that lldb uses slightly different naming conventions from sys/user.h
- switch (reg)
- {
- default:
- return false;
- case fpu_dp:
- value = m_fpr.xstate.fxsave.dp;
- break;
- case fpu_fcw:
- value = m_fpr.xstate.fxsave.fcw;
- break;
- case fpu_fsw:
- value = m_fpr.xstate.fxsave.fsw;
- break;
- case fpu_ip:
- value = m_fpr.xstate.fxsave.ip;
- break;
- case fpu_fop:
- value = m_fpr.xstate.fxsave.fop;
- break;
- case fpu_ftw:
- value = m_fpr.xstate.fxsave.ftw;
- break;
- case fpu_mxcsr:
- value = m_fpr.xstate.fxsave.mxcsr;
- break;
- case fpu_mxcsrmask:
- value = m_fpr.xstate.fxsave.mxcsrmask;
- break;
- }
- return true;
-}
-
-bool
-RegisterContext_x86_64::ReadAllRegisterValues(DataBufferSP &data_sp)
-{
- bool success = false;
- data_sp.reset (new DataBufferHeap (REG_CONTEXT_SIZE, 0));
- if (data_sp && ReadGPR () && ReadFPR ())
- {
- uint8_t *dst = data_sp->GetBytes();
- success = dst != 0;
-
- if (success) {
- ::memcpy (dst, &m_gpr, GetGPRSize());
- dst += GetGPRSize();
- }
- if (m_fpr_type == eFXSAVE)
- ::memcpy (dst, &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
-
- if (m_fpr_type == eXSAVE) {
- ByteOrder byte_order = GetByteOrder();
-
- // Assemble the YMM register content from the register halves.
- for (uint32_t reg = fpu_ymm0; success && reg <= fpu_ymm15; ++reg)
- success = CopyXSTATEtoYMM(reg, byte_order);
-
- if (success) {
- // Copy the extended register state including the assembled ymm registers.
- ::memcpy (dst, &m_fpr, sizeof(m_fpr));
- }
- }
- }
- return success;
-}
-
-bool
-RegisterContext_x86_64::WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value)
-{
- const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- if (IsGPR(reg)) {
- return WriteRegister(reg, value);
- }
-
- if (IsFPR(reg, m_fpr_type)) {
- switch (reg)
- {
- default:
- if (reg_info->encoding != eEncodingVector)
- return false;
-
- if (reg >= fpu_stmm0 && reg <= fpu_stmm7)
- ::memcpy (m_fpr.xstate.fxsave.stmm[reg - fpu_stmm0].bytes, value.GetBytes(), value.GetByteSize());
-
- if (reg >= fpu_xmm0 && reg <= fpu_xmm15)
- ::memcpy (m_fpr.xstate.fxsave.xmm[reg - fpu_xmm0].bytes, value.GetBytes(), value.GetByteSize());
-
- if (reg >= fpu_ymm0 && reg <= fpu_ymm15) {
- if (m_fpr_type != eXSAVE)
- return false; // the target processor does not support AVX
-
- // Store ymm register content, and split into the register halves in xmm.bytes and ymmh.bytes
- ::memcpy (m_ymm_set.ymm[reg - fpu_ymm0].bytes, value.GetBytes(), value.GetByteSize());
- if (false == CopyYMMtoXSTATE(reg, GetByteOrder()))
- return false;
- }
- break;
- case fpu_dp:
- m_fpr.xstate.fxsave.dp = value.GetAsUInt64();
- break;
- case fpu_fcw:
- m_fpr.xstate.fxsave.fcw = value.GetAsUInt16();
- break;
- case fpu_fsw:
- m_fpr.xstate.fxsave.fsw = value.GetAsUInt16();
- break;
- case fpu_ip:
- m_fpr.xstate.fxsave.ip = value.GetAsUInt64();
- break;
- case fpu_fop:
- m_fpr.xstate.fxsave.fop = value.GetAsUInt16();
- break;
- case fpu_ftw:
- m_fpr.xstate.fxsave.ftw = value.GetAsUInt16();
- break;
- case fpu_mxcsr:
- m_fpr.xstate.fxsave.mxcsr = value.GetAsUInt32();
- break;
- case fpu_mxcsrmask:
- m_fpr.xstate.fxsave.mxcsrmask = value.GetAsUInt32();
- break;
- }
- if (WriteFPR()) {
- if (IsAVX(reg))
- return CopyYMMtoXSTATE(reg, GetByteOrder());
- return true;
- }
- }
- return false;
-}
-
-bool
-RegisterContext_x86_64::WriteAllRegisterValues(const DataBufferSP &data_sp)
-{
- bool success = false;
- if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE)
- {
- uint8_t *src = data_sp->GetBytes();
- if (src) {
- ::memcpy (&m_gpr, src, GetGPRSize());
-
- if (WriteGPR()) {
- src += GetGPRSize();
- if (m_fpr_type == eFXSAVE)
- ::memcpy (&m_fpr.xstate.fxsave, src, sizeof(m_fpr.xstate.fxsave));
- if (m_fpr_type == eXSAVE)
- ::memcpy (&m_fpr.xstate.xsave, src, sizeof(m_fpr.xstate.xsave));
-
- success = WriteFPR();
- if (success) {
- success = true;
-
- if (m_fpr_type == eXSAVE) {
- ByteOrder byte_order = GetByteOrder();
-
- // Parse the YMM register content from the register halves.
- for (uint32_t reg = fpu_ymm0; success && reg <= fpu_ymm15; ++reg)
- success = CopyYMMtoXSTATE(reg, byte_order);
- }
- }
- }
- }
- }
- return success;
-}
-
-bool
-RegisterContext_x86_64::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
-RegisterContext_x86_64::ConvertRegisterKindToRegisterNumber(uint32_t kind,
- uint32_t num)
-{
- const Process *process = CalculateProcess().get();
- if (process)
- {
- const ArchSpec arch = process->GetTarget().GetArchitecture();;
- switch (arch.GetCore())
- {
- default:
- 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:
- {
- 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_ds; //fpu_fos
- case gdb_dp : return fpu_dp; //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;
- }
-
- break;
- }
-
- case ArchSpec::eCore_x86_64_x86_64:
- {
- if (kind == eRegisterKindGeneric)
- {
- switch (num)
- {
- case LLDB_REGNUM_GENERIC_PC: return gpr_rip;
- case LLDB_REGNUM_GENERIC_SP: return gpr_rsp;
- case LLDB_REGNUM_GENERIC_FP: return gpr_rbp;
- case LLDB_REGNUM_GENERIC_FLAGS: return gpr_rflags;
- case LLDB_REGNUM_GENERIC_RA:
- default:
- return LLDB_INVALID_REGNUM;
- }
- }
-
- if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF)
- {
- switch (num)
- {
- case gcc_dwarf_gpr_rax: return gpr_rax;
- case gcc_dwarf_gpr_rdx: return gpr_rdx;
- case gcc_dwarf_gpr_rcx: return gpr_rcx;
- case gcc_dwarf_gpr_rbx: return gpr_rbx;
- case gcc_dwarf_gpr_rsi: return gpr_rsi;
- case gcc_dwarf_gpr_rdi: return gpr_rdi;
- case gcc_dwarf_gpr_rbp: return gpr_rbp;
- case gcc_dwarf_gpr_rsp: return gpr_rsp;
- case gcc_dwarf_gpr_r8: return gpr_r8;
- case gcc_dwarf_gpr_r9: return gpr_r9;
- case gcc_dwarf_gpr_r10: return gpr_r10;
- case gcc_dwarf_gpr_r11: return gpr_r11;
- case gcc_dwarf_gpr_r12: return gpr_r12;
- case gcc_dwarf_gpr_r13: return gpr_r13;
- case gcc_dwarf_gpr_r14: return gpr_r14;
- case gcc_dwarf_gpr_r15: return gpr_r15;
- case gcc_dwarf_gpr_rip: return gpr_rip;
- case gcc_dwarf_fpu_xmm0: return fpu_xmm0;
- case gcc_dwarf_fpu_xmm1: return fpu_xmm1;
- case gcc_dwarf_fpu_xmm2: return fpu_xmm2;
- case gcc_dwarf_fpu_xmm3: return fpu_xmm3;
- case gcc_dwarf_fpu_xmm4: return fpu_xmm4;
- case gcc_dwarf_fpu_xmm5: return fpu_xmm5;
- case gcc_dwarf_fpu_xmm6: return fpu_xmm6;
- case gcc_dwarf_fpu_xmm7: return fpu_xmm7;
- case gcc_dwarf_fpu_xmm8: return fpu_xmm8;
- case gcc_dwarf_fpu_xmm9: return fpu_xmm9;
- case gcc_dwarf_fpu_xmm10: return fpu_xmm10;
- case gcc_dwarf_fpu_xmm11: return fpu_xmm11;
- case gcc_dwarf_fpu_xmm12: return fpu_xmm12;
- case gcc_dwarf_fpu_xmm13: return fpu_xmm13;
- case gcc_dwarf_fpu_xmm14: return fpu_xmm14;
- case gcc_dwarf_fpu_xmm15: return fpu_xmm15;
- case gcc_dwarf_fpu_stmm0: return fpu_stmm0;
- case gcc_dwarf_fpu_stmm1: return fpu_stmm1;
- case gcc_dwarf_fpu_stmm2: return fpu_stmm2;
- case gcc_dwarf_fpu_stmm3: return fpu_stmm3;
- case gcc_dwarf_fpu_stmm4: return fpu_stmm4;
- case gcc_dwarf_fpu_stmm5: return fpu_stmm5;
- case gcc_dwarf_fpu_stmm6: return fpu_stmm6;
- case gcc_dwarf_fpu_stmm7: return fpu_stmm7;
- case gcc_dwarf_fpu_ymm0: return fpu_ymm0;
- case gcc_dwarf_fpu_ymm1: return fpu_ymm1;
- case gcc_dwarf_fpu_ymm2: return fpu_ymm2;
- case gcc_dwarf_fpu_ymm3: return fpu_ymm3;
- case gcc_dwarf_fpu_ymm4: return fpu_ymm4;
- case gcc_dwarf_fpu_ymm5: return fpu_ymm5;
- case gcc_dwarf_fpu_ymm6: return fpu_ymm6;
- case gcc_dwarf_fpu_ymm7: return fpu_ymm7;
- case gcc_dwarf_fpu_ymm8: return fpu_ymm8;
- case gcc_dwarf_fpu_ymm9: return fpu_ymm9;
- case gcc_dwarf_fpu_ymm10: return fpu_ymm10;
- case gcc_dwarf_fpu_ymm11: return fpu_ymm11;
- case gcc_dwarf_fpu_ymm12: return fpu_ymm12;
- case gcc_dwarf_fpu_ymm13: return fpu_ymm13;
- case gcc_dwarf_fpu_ymm14: return fpu_ymm14;
- case gcc_dwarf_fpu_ymm15: return fpu_ymm15;
- default:
- return LLDB_INVALID_REGNUM;
- }
- }
-
- if (kind == eRegisterKindGDB)
- {
- switch (num)
- {
- case gdb_gpr_rax : return gpr_rax;
- case gdb_gpr_rbx : return gpr_rbx;
- case gdb_gpr_rcx : return gpr_rcx;
- case gdb_gpr_rdx : return gpr_rdx;
- case gdb_gpr_rsi : return gpr_rsi;
- case gdb_gpr_rdi : return gpr_rdi;
- case gdb_gpr_rbp : return gpr_rbp;
- case gdb_gpr_rsp : return gpr_rsp;
- case gdb_gpr_r8 : return gpr_r8;
- case gdb_gpr_r9 : return gpr_r9;
- case gdb_gpr_r10 : return gpr_r10;
- case gdb_gpr_r11 : return gpr_r11;
- case gdb_gpr_r12 : return gpr_r12;
- case gdb_gpr_r13 : return gpr_r13;
- case gdb_gpr_r14 : return gpr_r14;
- case gdb_gpr_r15 : return gpr_r15;
- case gdb_gpr_rip : return gpr_rip;
- case gdb_gpr_rflags : return gpr_rflags;
- case gdb_gpr_cs : return gpr_cs;
- case gdb_gpr_ss : return gpr_ss;
- case gdb_gpr_ds : return gpr_ds;
- case gdb_gpr_es : return gpr_es;
- case gdb_gpr_fs : return gpr_fs;
- case gdb_gpr_gs : return gpr_gs;
- case gdb_fpu_stmm0 : return fpu_stmm0;
- case gdb_fpu_stmm1 : return fpu_stmm1;
- case gdb_fpu_stmm2 : return fpu_stmm2;
- case gdb_fpu_stmm3 : return fpu_stmm3;
- case gdb_fpu_stmm4 : return fpu_stmm4;
- case gdb_fpu_stmm5 : return fpu_stmm5;
- case gdb_fpu_stmm6 : return fpu_stmm6;
- case gdb_fpu_stmm7 : return fpu_stmm7;
- case gdb_fpu_fcw : return fpu_fcw;
- case gdb_fpu_fsw : return fpu_fsw;
- case gdb_fpu_ftw : return fpu_ftw;
- case gdb_fpu_cs_64 : return fpu_cs;
- case gdb_fpu_ip : return fpu_ip;
- case gdb_fpu_ds_64 : return fpu_ds;
- case gdb_fpu_dp : return fpu_dp;
- case gdb_fpu_fop : return fpu_fop;
- case gdb_fpu_xmm0 : return fpu_xmm0;
- case gdb_fpu_xmm1 : return fpu_xmm1;
- case gdb_fpu_xmm2 : return fpu_xmm2;
- case gdb_fpu_xmm3 : return fpu_xmm3;
- case gdb_fpu_xmm4 : return fpu_xmm4;
- case gdb_fpu_xmm5 : return fpu_xmm5;
- case gdb_fpu_xmm6 : return fpu_xmm6;
- case gdb_fpu_xmm7 : return fpu_xmm7;
- case gdb_fpu_xmm8 : return fpu_xmm8;
- case gdb_fpu_xmm9 : return fpu_xmm9;
- case gdb_fpu_xmm10 : return fpu_xmm10;
- case gdb_fpu_xmm11 : return fpu_xmm11;
- case gdb_fpu_xmm12 : return fpu_xmm12;
- case gdb_fpu_xmm13 : return fpu_xmm13;
- case gdb_fpu_xmm14 : return fpu_xmm14;
- case gdb_fpu_xmm15 : return fpu_xmm15;
- case gdb_fpu_mxcsr : return fpu_mxcsr;
- case gdb_fpu_ymm0 : return fpu_ymm0;
- case gdb_fpu_ymm1 : return fpu_ymm1;
- case gdb_fpu_ymm2 : return fpu_ymm2;
- case gdb_fpu_ymm3 : return fpu_ymm3;
- case gdb_fpu_ymm4 : return fpu_ymm4;
- case gdb_fpu_ymm5 : return fpu_ymm5;
- case gdb_fpu_ymm6 : return fpu_ymm6;
- case gdb_fpu_ymm7 : return fpu_ymm7;
- case gdb_fpu_ymm8 : return fpu_ymm8;
- case gdb_fpu_ymm9 : return fpu_ymm9;
- case gdb_fpu_ymm10 : return fpu_ymm10;
- case gdb_fpu_ymm11 : return fpu_ymm11;
- case gdb_fpu_ymm12 : return fpu_ymm12;
- case gdb_fpu_ymm13 : return fpu_ymm13;
- case gdb_fpu_ymm14 : return fpu_ymm14;
- case gdb_fpu_ymm15 : return fpu_ymm15;
- default:
- return LLDB_INVALID_REGNUM;
- }
- }
- else if (kind == eRegisterKindLLDB)
- {
- return num;
- }
- }
- }
- }
-
- return LLDB_INVALID_REGNUM;
-}
-
-uint32_t
-RegisterContext_x86_64::NumSupportedHardwareWatchpoints()
-{
- // Available debug address registers: dr0, dr1, dr2, dr3
- return 4;
-}
-
-bool
-RegisterContext_x86_64::IsWatchpointVacant(uint32_t hw_index)
-{
- bool is_vacant = false;
- RegisterValue value;
-
- assert(hw_index < NumSupportedHardwareWatchpoints());
-
- if (m_watchpoints_initialized == false)
- {
- // Reset the debug status and debug control registers
- RegisterValue zero_bits = RegisterValue(uint64_t(0));
- if (!WriteRegister(dr6, zero_bits) || !WriteRegister(dr7, zero_bits))
- assert(false && "Could not initialize watchpoint registers");
- m_watchpoints_initialized = true;
- }
-
- if (ReadRegister(dr7, value))
- {
- uint64_t val = value.GetAsUInt64();
- is_vacant = (val & (3 << 2*hw_index)) == 0;
- }
-
- return is_vacant;
-}
-
-static uint32_t
-size_and_rw_bits(size_t size, bool read, bool write)
-{
- uint32_t rw;
- if (read) {
- rw = 0x3; // READ or READ/WRITE
- } else if (write) {
- rw = 0x1; // WRITE
- } else {
- assert(0 && "read and write cannot both be false");
- }
-
- switch (size) {
- case 1:
- return rw;
- case 2:
- return (0x1 << 2) | rw;
- case 4:
- return (0x3 << 2) | rw;
- case 8:
- return (0x2 << 2) | rw;
- default:
- assert(0 && "invalid size, must be one of 1, 2, 4, or 8");
- }
-}
-
-uint32_t
-RegisterContext_x86_64::SetHardwareWatchpoint(addr_t addr, size_t size,
- bool read, bool write)
-{
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
- uint32_t hw_index;
-
- for (hw_index = 0; hw_index < num_hw_watchpoints; ++hw_index)
- {
- if (IsWatchpointVacant(hw_index))
- return SetHardwareWatchpointWithIndex(addr, size,
- read, write,
- hw_index);
- }
-
- return LLDB_INVALID_INDEX32;
-}
-
-bool
-RegisterContext_x86_64::SetHardwareWatchpointWithIndex(addr_t addr, size_t size,
- bool read, bool write,
- uint32_t hw_index)
-{
- const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();
-
- if (num_hw_watchpoints == 0 || hw_index >= num_hw_watchpoints)
- return false;
-
- if (!(size == 1 || size == 2 || size == 4 || size == 8))
- return false;
-
- if (read == false && write == false)
- return false;
-
- if (!IsWatchpointVacant(hw_index))
- return false;
-
- // Set both dr7 (debug control register) and dri (debug address register).
-
- // dr7{7-0} encodes the local/gloabl enable bits:
- // global enable --. .-- local enable
- // | |
- // v v
- // dr0 -> bits{1-0}
- // dr1 -> bits{3-2}
- // dr2 -> bits{5-4}
- // dr3 -> bits{7-6}
- //
- // dr7{31-16} encodes the rw/len bits:
- // b_x+3, b_x+2, b_x+1, b_x
- // where bits{x+1, x} => rw
- // 0b00: execute, 0b01: write, 0b11: read-or-write,
- // 0b10: io read-or-write (unused)
- // and bits{x+3, x+2} => len
- // 0b00: 1-byte, 0b01: 2-byte, 0b11: 4-byte, 0b10: 8-byte
- //
- // dr0 -> bits{19-16}
- // dr1 -> bits{23-20}
- // dr2 -> bits{27-24}
- // dr3 -> bits{31-28}
- if (hw_index < num_hw_watchpoints)
- {
- RegisterValue current_dr7_bits;
-
- if (ReadRegister(dr7, current_dr7_bits))
- {
- uint64_t new_dr7_bits = current_dr7_bits.GetAsUInt64() |
- (1 << (2*hw_index) |
- size_and_rw_bits(size, read, write) <<
- (16+4*hw_index));
-
- if (WriteRegister(dr0 + hw_index, RegisterValue(addr)) &&
- WriteRegister(dr7, RegisterValue(new_dr7_bits)))
- return true;
- }
- }
-
- return false;
-}
-
-bool
-RegisterContext_x86_64::ClearHardwareWatchpoint(uint32_t hw_index)
-{
- if (hw_index < NumSupportedHardwareWatchpoints())
- {
- RegisterValue current_dr7_bits;
-
- if (ReadRegister(dr7, current_dr7_bits))
- {
- uint64_t new_dr7_bits = current_dr7_bits.GetAsUInt64() & ~(3 << (2*hw_index));
-
- if (WriteRegister(dr7, RegisterValue(new_dr7_bits)))
- return true;
- }
- }
-
- return false;
-}
-
-bool
-RegisterContext_x86_64::IsWatchpointHit(uint32_t hw_index)
-{
- bool is_hit = false;
-
- if (m_watchpoints_initialized == false)
- {
- // Reset the debug status and debug control registers
- RegisterValue zero_bits = RegisterValue(uint64_t(0));
- if (!WriteRegister(dr6, zero_bits) || !WriteRegister(dr7, zero_bits))
- assert(false && "Could not initialize watchpoint registers");
- m_watchpoints_initialized = true;
- }
-
- if (hw_index < NumSupportedHardwareWatchpoints())
- {
- RegisterValue value;
-
- if (ReadRegister(dr6, value))
- {
- uint64_t val = value.GetAsUInt64();
- is_hit = val & (1 << hw_index);
- }
- }
-
- return is_hit;
-}
-
-addr_t
-RegisterContext_x86_64::GetWatchpointAddress(uint32_t hw_index)
-{
- addr_t wp_monitor_addr = LLDB_INVALID_ADDRESS;
-
- if (hw_index < NumSupportedHardwareWatchpoints())
- {
- if (!IsWatchpointVacant(hw_index))
- {
- RegisterValue value;
-
- if (ReadRegister(dr0 + hw_index, value))
- wp_monitor_addr = value.GetAsUInt64();
- }
- }
-
- return wp_monitor_addr;
-}
-
-
-bool
-RegisterContext_x86_64::ClearWatchpointHits()
-{
- return WriteRegister(dr6, RegisterValue((uint64_t)0));
-}
-
-bool
-RegisterContext_x86_64::HardwareSingleStep(bool enable)
-{
- enum { TRACE_BIT = 0x100 };
- uint64_t rflags;
-
- if ((rflags = ReadRegisterAsUnsigned(gpr_rflags, -1UL)) == -1UL)
- return false;
-
- if (enable)
- {
- if (rflags & TRACE_BIT)
- return true;
-
- rflags |= TRACE_BIT;
- }
- else
- {
- if (!(rflags & TRACE_BIT))
- return false;
-
- rflags &= ~TRACE_BIT;
- }
-
- return WriteRegisterFromUnsigned(gpr_rflags, rflags);
-}
-
-#if defined(__linux__) or defined(__FreeBSD__)
-
-ProcessMonitor &
-RegisterContext_x86_64::GetMonitor()
-{
- ProcessSP base = CalculateProcess();
- ProcessPOSIX *process = static_cast<ProcessPOSIX*>(base.get());
- return process->GetMonitor();
-}
-
-bool
-RegisterContext_x86_64::ReadGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(m_thread.GetID(), &m_gpr, GetGPRSize());
-}
-
-bool
-RegisterContext_x86_64::ReadFPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- if (m_fpr_type == eFXSAVE)
- return monitor.ReadFPR(m_thread.GetID(), &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
-
- if (m_fpr_type == eXSAVE)
- return monitor.ReadRegisterSet(m_thread.GetID(), &m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
- return false;
-}
-
-bool
-RegisterContext_x86_64::WriteGPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteGPR(m_thread.GetID(), &m_gpr, GetGPRSize());
-}
-
-bool
-RegisterContext_x86_64::WriteFPR()
-{
- ProcessMonitor &monitor = GetMonitor();
- if (m_fpr_type == eFXSAVE)
- return monitor.WriteFPR(m_thread.GetID(), &m_fpr.xstate.fxsave, sizeof(m_fpr.xstate.fxsave));
-
- if (m_fpr_type == eXSAVE)
- return monitor.WriteRegisterSet(m_thread.GetID(), &m_iovec, sizeof(m_fpr.xstate.xsave), NT_X86_XSTATE);
- return false;
-}
-
-bool
-RegisterContext_x86_64::ReadRegister(const unsigned reg,
- RegisterValue &value)
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg),
- GetRegisterName(reg),
- GetRegisterSize(reg),
- value);
-}
-
-bool
-RegisterContext_x86_64::WriteRegister(const unsigned reg,
- const RegisterValue &value)
-{
- ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteRegisterValue(m_thread.GetID(),
- GetRegisterOffset(reg),
- GetRegisterName(reg),
- value);
-}
-
-#else
-
-bool
-RegisterContext_x86_64::ReadGPR()
-{
- llvm_unreachable("not implemented");
- return false;
-}
-
-bool
-RegisterContext_x86_64::ReadFPR()
-{
- llvm_unreachable("not implemented");
- return false;
-}
-
-bool
-RegisterContext_x86_64::WriteGPR()
-{
- llvm_unreachable("not implemented");
- return false;
-}
-
-bool
-RegisterContext_x86_64::WriteFPR()
-{
- llvm_unreachable("not implemented");
- return false;
-}
-
-bool
-RegisterContext_x86_64::ReadRegister(const unsigned reg,
- RegisterValue &value)
-{
- llvm_unreachable("not implemented");
- return false;
-}
-
-bool
-RegisterContext_x86_64::WriteRegister(const unsigned reg,
- const RegisterValue &value)
-{
- llvm_unreachable("not implemented");
- return false;
-}
-
-#endif
diff --git a/source/Plugins/Process/POSIX/RegisterContext_x86_64.h b/source/Plugins/Process/POSIX/RegisterContext_x86_64.h
deleted file mode 100644
index 9d59bd78e547..000000000000
--- a/source/Plugins/Process/POSIX/RegisterContext_x86_64.h
+++ /dev/null
@@ -1,347 +0,0 @@
-//===-- RegisterContext_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_RegisterContext_x86_64_H_
-#define liblldb_RegisterContext_x86_64_H_
-
-#include "lldb/Core/Log.h"
-#include "RegisterContextPOSIX.h"
-
-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,
- k_first_i386,
- gpr_eax = k_first_i386,
- gpr_ebx,
- gpr_ecx,
- gpr_edx,
- gpr_edi,
- gpr_esi,
- gpr_ebp,
- gpr_esp,
- gpr_eip,
- gpr_eflags, // eRegisterKindLLDB == 33
- k_last_i386 = gpr_eflags,
- k_last_gpr = gpr_eflags,
-
- 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,
-
- dr0,
- dr1,
- dr2,
- dr3,
- dr4,
- dr5,
- dr6,
- dr7,
-
- 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);
-
- ~RegisterContext_x86_64();
-
- void
- Invalidate();
-
- void
- InvalidateAllRegisters();
-
- 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);
-
- size_t
- GetRegisterSetCount();
-
- const lldb_private::RegisterSet *
- GetRegisterSet(size_t set);
-
- unsigned
- GetRegisterIndexFromOffset(unsigned offset);
-
- const char *
- GetRegisterName(unsigned reg);
-
- virtual bool
- ReadRegister(const lldb_private::RegisterInfo *reg_info,
- lldb_private::RegisterValue &value);
-
- bool
- ReadAllRegisterValues(lldb::DataBufferSP &data_sp);
-
- virtual bool
- WriteRegister(const lldb_private::RegisterInfo *reg_info,
- const lldb_private::RegisterValue &value);
-
- bool
- WriteAllRegisterValues(const lldb::DataBufferSP &data_sp);
-
- uint32_t
- ConvertRegisterKindToRegisterNumber(uint32_t kind, uint32_t num);
-
- uint32_t
- NumSupportedHardwareWatchpoints();
-
- uint32_t
- SetHardwareWatchpoint(lldb::addr_t, size_t size, bool read, bool write);
-
- bool
- SetHardwareWatchpointWithIndex(lldb::addr_t, size_t size, bool read,
- bool write, uint32_t hw_index);
-
- bool
- ClearHardwareWatchpoint(uint32_t hw_index);
-
- bool
- HardwareSingleStep(bool enable);
-
- bool
- UpdateAfterBreakpoint();
-
- bool
- IsWatchpointVacant(uint32_t hw_index);
-
- bool
- IsWatchpointHit (uint32_t hw_index);
-
- lldb::addr_t
- GetWatchpointAddress (uint32_t hw_index);
-
- bool
- ClearWatchpointHits();
-
- //---------------------------------------------------------------------------
- // Generic floating-point registers
- //---------------------------------------------------------------------------
-
- struct MMSReg
- {
- uint8_t bytes[10];
- uint8_t pad[6];
- };
-
- struct XMMReg
- {
- uint8_t bytes[16]; // 128-bits for each XMM register
- };
-
- struct FXSAVE
- {
- uint16_t fcw;
- uint16_t fsw;
- uint16_t ftw;
- uint16_t fop;
- uint64_t ip;
- uint64_t dp;
- uint32_t mxcsr;
- uint32_t mxcsrmask;
- MMSReg stmm[8];
- XMMReg xmm[16];
- uint32_t padding[24];
- };
-
- //---------------------------------------------------------------------------
- // Extended floating-point registers
- //---------------------------------------------------------------------------
- struct YMMHReg
- {
- uint8_t bytes[16]; // 16 * 8 bits for the high bytes of each YMM register
- };
-
- struct YMMReg
- {
- uint8_t bytes[32]; // 16 * 16 bits for each YMM register
- };
-
- struct YMM
- {
- YMMReg ymm[16]; // assembled from ymmh and xmm registers
- };
-
- struct XSAVE_HDR
- {
- uint64_t xstate_bv; // OS enabled xstate mask to determine the extended states supported by the processor
- uint64_t reserved1[2];
- uint64_t reserved2[5];
- } __attribute__((packed));
-
- // x86 extensions to FXSAVE (i.e. for AVX processors)
- struct XSAVE
- {
- FXSAVE i387; // floating point registers typical in i387_fxsave_struct
- XSAVE_HDR header; // The xsave_hdr_struct can be used to determine if the following extensions are usable
- YMMHReg ymmh[16]; // High 16 bytes of each of 16 YMM registers (the low bytes are in FXSAVE.xmm for compatibility with SSE)
- // Slot any extensions to the register file here
- } __attribute__((packed, aligned (64)));
-
- struct IOVEC
- {
- void *iov_base; // pointer to XSAVE
- size_t iov_len; // sizeof(XSAVE)
- };
-
- //---------------------------------------------------------------------------
- // Note: prefer kernel definitions over user-land
- //---------------------------------------------------------------------------
- enum FPRType
- {
- eNotValid = 0,
- eFSAVE, // TODO
- eFXSAVE,
- eSOFT, // TODO
- eXSAVE
- };
-
- // Floating-point registers
- struct FPR
- {
- // Thread state for the floating-point unit of the processor read by ptrace.
- union XSTATE {
- FXSAVE fxsave; // Generic floating-point registers.
- XSAVE xsave; // x86 extended processor state.
- } xstate;
- };
-
-protected:
- // Determines if an extended register set is supported on the processor running the inferior process.
- virtual bool
- IsRegisterSetAvailable(size_t set_index);
-
- virtual const lldb_private::RegisterInfo *
- GetRegisterInfo();
-
- virtual bool
- ReadRegister(const unsigned reg, lldb_private::RegisterValue &value);
-
- virtual bool
- WriteRegister(const unsigned reg, const lldb_private::RegisterValue &value);
-
-private:
- uint64_t m_gpr[k_num_gpr_registers]; // general purpose registers.
- FPRType m_fpr_type; // determines the type of data stored by union FPR, if any.
- FPR m_fpr; // floating-point registers including extended register sets.
- IOVEC m_iovec; // wrapper for xsave.
- YMM m_ymm_set; // copy of ymmh and xmm register halves.
-
- ProcessMonitor &GetMonitor();
- lldb::ByteOrder GetByteOrder();
-
- bool CopyXSTATEtoYMM(uint32_t reg, lldb::ByteOrder byte_order);
- bool CopyYMMtoXSTATE(uint32_t reg, lldb::ByteOrder byte_order);
- bool IsFPR(unsigned reg, FPRType fpr_type);
-
- bool ReadGPR();
- bool ReadFPR();
-
- bool WriteGPR();
- bool WriteFPR();
-};
-
-#endif // #ifndef liblldb_RegisterContext_x86_64_H_
diff --git a/source/Plugins/Process/POSIX/RegisterInfos_i386.h b/source/Plugins/Process/POSIX/RegisterInfos_i386.h
new file mode 100644
index 000000000000..7c516568cd62
--- /dev/null
+++ b/source/Plugins/Process/POSIX/RegisterInfos_i386.h
@@ -0,0 +1,207 @@
+//===-- RegisterInfos_i386.h -----------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+#include "llvm/Support/Compiler.h"
+
+#ifdef DECLARE_REGISTER_INFOS_I386_STRUCT
+
+// Computes the offset of the given GPR in the user data area.
+#define GPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(GPR, regname))
+
+// Computes the offset of the given FPR in the extended data area.
+#define FPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(FXSAVE, regname))
+
+// Computes the offset of the YMM register assembled from register halves.
+#define YMM_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(YMM, regname))
+
+// Number of bytes needed to represent a FPR.
+#define FPR_SIZE(reg) sizeof(((FXSAVE*)NULL)->reg)
+
+// Number of bytes needed to represent the i'th FP register.
+#define FP_SIZE sizeof(((MMSReg*)NULL)->bytes)
+
+// Number of bytes needed to represent an XMM register.
+#define XMM_SIZE sizeof(XMMReg)
+
+// Number of bytes needed to represent a YMM register.
+#define YMM_SIZE sizeof(YMMReg)
+
+// Note that the size and offset will be updated by platform-specific classes.
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
+ { #reg, alt, sizeof(GPR::reg), GPR_OFFSET(reg), eEncodingUint, \
+ eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_i386 }, NULL, NULL }
+
+#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \
+ { #name, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \
+ eFormatHex, { kind1, kind2, kind3, kind4, fpu_##name##_i386 }, NULL, NULL }
+
+// RegisterKind: GCC, DWARF, Generic, GDB, LLDB
+
+#define DEFINE_FP_ST(reg, i) \
+ { #reg#i, NULL, FP_SIZE, LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
+ eEncodingVector, eFormatVectorOfUInt8, \
+ { gcc_st##i##_i386, dwarf_st##i##_i386, LLDB_INVALID_REGNUM, gdb_st##i##_i386, fpu_st##i##_i386 }, \
+ NULL, NULL }
+
+#define DEFINE_FP_MM(reg, i) \
+ { #reg#i, NULL, sizeof(uint64_t), LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
+ eEncodingUint, eFormatHex, \
+ { gcc_mm##i##_i386, dwarf_mm##i##_i386, LLDB_INVALID_REGNUM, gdb_mm##i##_i386, fpu_mm##i##_i386 }, \
+ NULL, NULL }
+
+#define DEFINE_XMM(reg, i) \
+ { #reg#i, NULL, XMM_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \
+ eEncodingVector, eFormatVectorOfUInt8, \
+ { gcc_##reg##i##_i386, dwarf_##reg##i##_i386, LLDB_INVALID_REGNUM, gdb_##reg##i##_i386, fpu_##reg##i##_i386}, \
+ NULL, NULL }
+
+// I believe the YMM registers use dwarf_xmm_%_i386 register numbers and then differentiate based on register size.
+#define DEFINE_YMM(reg, i) \
+ { #reg#i, NULL, YMM_SIZE, LLVM_EXTENSION YMM_OFFSET(reg[i]), \
+ eEncodingVector, eFormatVectorOfUInt8, \
+ { LLDB_INVALID_REGNUM, dwarf_xmm##i##_i386, LLDB_INVALID_REGNUM, gdb_##reg##i##h_i386, fpu_##reg##i##_i386 }, \
+ NULL, NULL }
+
+#define DEFINE_DR(reg, i) \
+ { #reg#i, NULL, DR_SIZE, DR_OFFSET(i), eEncodingUint, eFormatHex, \
+ { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL }
+
+#define DEFINE_GPR_PSEUDO_16(reg16, reg32) \
+ { #reg16, NULL, 2, GPR_OFFSET(reg32), eEncodingUint, \
+ eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_##reg16##_i386 }, RegisterContextPOSIX_x86::g_contained_##reg32, RegisterContextPOSIX_x86::g_invalidate_##reg32 }
+#define DEFINE_GPR_PSEUDO_8H(reg8, reg32) \
+ { #reg8, NULL, 1, GPR_OFFSET(reg32)+1, eEncodingUint, \
+ eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_##reg8##_i386 }, RegisterContextPOSIX_x86::g_contained_##reg32, RegisterContextPOSIX_x86::g_invalidate_##reg32 }
+#define DEFINE_GPR_PSEUDO_8L(reg8, reg32) \
+ { #reg8, NULL, 1, GPR_OFFSET(reg32), eEncodingUint, \
+ eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_##reg8##_i386 }, RegisterContextPOSIX_x86::g_contained_##reg32, RegisterContextPOSIX_x86::g_invalidate_##reg32 }
+
+static RegisterInfo
+g_register_infos_i386[] =
+{
+ // General purpose registers.
+ DEFINE_GPR(eax, NULL, gcc_eax_i386, dwarf_eax_i386, LLDB_INVALID_REGNUM, gdb_eax_i386),
+ DEFINE_GPR(ebx, NULL, gcc_ebx_i386, dwarf_ebx_i386, LLDB_INVALID_REGNUM, gdb_ebx_i386),
+ DEFINE_GPR(ecx, NULL, gcc_ecx_i386, dwarf_ecx_i386, LLDB_INVALID_REGNUM, gdb_ecx_i386),
+ DEFINE_GPR(edx, NULL, gcc_edx_i386, dwarf_edx_i386, LLDB_INVALID_REGNUM, gdb_edx_i386),
+ DEFINE_GPR(edi, NULL, gcc_edi_i386, dwarf_edi_i386, LLDB_INVALID_REGNUM, gdb_edi_i386),
+ DEFINE_GPR(esi, NULL, gcc_esi_i386, dwarf_esi_i386, LLDB_INVALID_REGNUM, gdb_esi_i386),
+ DEFINE_GPR(ebp, "fp", gcc_ebp_i386, dwarf_ebp_i386, LLDB_REGNUM_GENERIC_FP, gdb_ebp_i386),
+ DEFINE_GPR(esp, "sp", gcc_esp_i386, dwarf_esp_i386, LLDB_REGNUM_GENERIC_SP, gdb_esp_i386),
+ DEFINE_GPR(eip, "pc", gcc_eip_i386, dwarf_eip_i386, LLDB_REGNUM_GENERIC_PC, gdb_eip_i386),
+ DEFINE_GPR(eflags, "flags", gcc_eflags_i386, dwarf_eflags_i386, LLDB_REGNUM_GENERIC_FLAGS, gdb_eflags_i386),
+ DEFINE_GPR(cs, NULL, LLDB_INVALID_REGNUM, dwarf_cs_i386, LLDB_INVALID_REGNUM, gdb_cs_i386),
+ DEFINE_GPR(fs, NULL, LLDB_INVALID_REGNUM, dwarf_fs_i386, LLDB_INVALID_REGNUM, gdb_fs_i386),
+ DEFINE_GPR(gs, NULL, LLDB_INVALID_REGNUM, dwarf_gs_i386, LLDB_INVALID_REGNUM, gdb_gs_i386),
+ DEFINE_GPR(ss, NULL, LLDB_INVALID_REGNUM, dwarf_ss_i386, LLDB_INVALID_REGNUM, gdb_ss_i386),
+ DEFINE_GPR(ds, NULL, LLDB_INVALID_REGNUM, dwarf_ds_i386, LLDB_INVALID_REGNUM, gdb_ds_i386),
+ DEFINE_GPR(es, NULL, LLDB_INVALID_REGNUM, dwarf_es_i386, LLDB_INVALID_REGNUM, gdb_es_i386),
+
+ DEFINE_GPR_PSEUDO_16(ax, eax),
+ DEFINE_GPR_PSEUDO_16(bx, ebx),
+ DEFINE_GPR_PSEUDO_16(cx, ecx),
+ DEFINE_GPR_PSEUDO_16(dx, edx),
+ DEFINE_GPR_PSEUDO_16(di, edi),
+ DEFINE_GPR_PSEUDO_16(si, esi),
+ DEFINE_GPR_PSEUDO_16(bp, ebp),
+ DEFINE_GPR_PSEUDO_16(sp, esp),
+ DEFINE_GPR_PSEUDO_8H(ah, eax),
+ DEFINE_GPR_PSEUDO_8H(bh, ebx),
+ DEFINE_GPR_PSEUDO_8H(ch, ecx),
+ DEFINE_GPR_PSEUDO_8H(dh, edx),
+ DEFINE_GPR_PSEUDO_8L(al, eax),
+ DEFINE_GPR_PSEUDO_8L(bl, ebx),
+ DEFINE_GPR_PSEUDO_8L(cl, ecx),
+ DEFINE_GPR_PSEUDO_8L(dl, edx),
+
+ // i387 Floating point registers.
+ DEFINE_FPR(fctrl, fctrl, LLDB_INVALID_REGNUM, dwarf_fctrl_i386, LLDB_INVALID_REGNUM, gdb_fctrl_i386),
+ DEFINE_FPR(fstat, fstat, LLDB_INVALID_REGNUM, dwarf_fstat_i386, LLDB_INVALID_REGNUM, gdb_fstat_i386),
+ DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ftag_i386),
+ DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fop_i386),
+ DEFINE_FPR(fiseg, ptr.i386.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fiseg_i386),
+ DEFINE_FPR(fioff, ptr.i386.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fioff_i386),
+ DEFINE_FPR(foseg, ptr.i386.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_foseg_i386),
+ DEFINE_FPR(fooff, ptr.i386.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fooff_i386),
+ DEFINE_FPR(mxcsr, mxcsr, LLDB_INVALID_REGNUM, dwarf_mxcsr_i386, LLDB_INVALID_REGNUM, gdb_mxcsr_i386),
+ DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+
+ // FP registers.
+ DEFINE_FP_ST(st, 0),
+ DEFINE_FP_ST(st, 1),
+ DEFINE_FP_ST(st, 2),
+ DEFINE_FP_ST(st, 3),
+ DEFINE_FP_ST(st, 4),
+ DEFINE_FP_ST(st, 5),
+ DEFINE_FP_ST(st, 6),
+ DEFINE_FP_ST(st, 7),
+ DEFINE_FP_MM(mm, 0),
+ DEFINE_FP_MM(mm, 1),
+ DEFINE_FP_MM(mm, 2),
+ DEFINE_FP_MM(mm, 3),
+ DEFINE_FP_MM(mm, 4),
+ DEFINE_FP_MM(mm, 5),
+ DEFINE_FP_MM(mm, 6),
+ DEFINE_FP_MM(mm, 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),
+
+ // Copy of YMM registers assembled from xmm and ymmh
+ DEFINE_YMM(ymm, 0),
+ DEFINE_YMM(ymm, 1),
+ DEFINE_YMM(ymm, 2),
+ DEFINE_YMM(ymm, 3),
+ DEFINE_YMM(ymm, 4),
+ DEFINE_YMM(ymm, 5),
+ DEFINE_YMM(ymm, 6),
+ DEFINE_YMM(ymm, 7),
+
+ // Debug registers for lldb internal use
+ DEFINE_DR(dr, 0),
+ DEFINE_DR(dr, 1),
+ DEFINE_DR(dr, 2),
+ DEFINE_DR(dr, 3),
+ DEFINE_DR(dr, 4),
+ DEFINE_DR(dr, 5),
+ DEFINE_DR(dr, 6),
+ DEFINE_DR(dr, 7)
+};
+static_assert((sizeof(g_register_infos_i386) / sizeof(g_register_infos_i386[0])) == k_num_registers_i386,
+ "g_register_infos_x86_64 has wrong number of register infos");
+
+#undef GPR_OFFSET
+#undef FPR_OFFSET
+#undef YMM_OFFSET
+#undef FPR_SIZE
+#undef FP_SIZE
+#undef XMM_SIZE
+#undef YMM_SIZE
+#undef DEFINE_GPR
+#undef DEFINE_FPR
+#undef DEFINE_FP
+#undef DEFINE_XMM
+#undef DEFINE_YMM
+#undef DEFINE_DR
+#undef DEFINE_GPR_PSEUDO_16
+#undef DEFINE_GPR_PSEUDO_8H
+#undef DEFINE_GPR_PSEUDO_8L
+
+#endif // DECLARE_REGISTER_INFOS_I386_STRUCT
diff --git a/source/Plugins/Process/POSIX/RegisterInfos_mips64.h b/source/Plugins/Process/POSIX/RegisterInfos_mips64.h
new file mode 100644
index 000000000000..13526e3680b7
--- /dev/null
+++ b/source/Plugins/Process/POSIX/RegisterInfos_mips64.h
@@ -0,0 +1,74 @@
+//===-- RegisterInfos_mips64.h ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===---------------------------------------------------------------------===//
+
+// Computes the offset of the given GPR in the user data area.
+#define GPR_OFFSET(regname) \
+ (offsetof(GPR, regname))
+
+#ifdef DECLARE_REGISTER_INFOS_MIPS64_STRUCT
+
+// Note that the size and offset will be updated by platform-specific classes.
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
+ { #reg, alt, sizeof(GPR::reg), GPR_OFFSET(reg), eEncodingUint, \
+ eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_mips64 }, NULL, NULL }
+
+static RegisterInfo
+g_register_infos_mips64[] =
+{
+ // General purpose registers. GCC, DWARF, Generic, GDB
+ DEFINE_GPR(zero, "r0", gcc_dwarf_zero_mips64, gcc_dwarf_zero_mips64, LLDB_INVALID_REGNUM, gdb_zero_mips64),
+ DEFINE_GPR(r1, NULL, gcc_dwarf_r1_mips64, gcc_dwarf_r1_mips64, LLDB_INVALID_REGNUM, gdb_r1_mips64),
+ DEFINE_GPR(r2, NULL, gcc_dwarf_r2_mips64, gcc_dwarf_r2_mips64, LLDB_INVALID_REGNUM, gdb_r2_mips64),
+ DEFINE_GPR(r3, NULL, gcc_dwarf_r3_mips64, gcc_dwarf_r3_mips64, LLDB_INVALID_REGNUM, gdb_r3_mips64),
+ DEFINE_GPR(r4, NULL, gcc_dwarf_r4_mips64, gcc_dwarf_r4_mips64, LLDB_INVALID_REGNUM, gdb_r4_mips64),
+ DEFINE_GPR(r5, NULL, gcc_dwarf_r5_mips64, gcc_dwarf_r5_mips64, LLDB_INVALID_REGNUM, gdb_r5_mips64),
+ DEFINE_GPR(r6, NULL, gcc_dwarf_r6_mips64, gcc_dwarf_r6_mips64, LLDB_INVALID_REGNUM, gdb_r6_mips64),
+ DEFINE_GPR(r7, NULL, gcc_dwarf_r7_mips64, gcc_dwarf_r7_mips64, LLDB_INVALID_REGNUM, gdb_r7_mips64),
+ DEFINE_GPR(r8, NULL, gcc_dwarf_r8_mips64, gcc_dwarf_r8_mips64, LLDB_INVALID_REGNUM, gdb_r8_mips64),
+ DEFINE_GPR(r9, NULL, gcc_dwarf_r9_mips64, gcc_dwarf_r9_mips64, LLDB_INVALID_REGNUM, gdb_r9_mips64),
+ DEFINE_GPR(r10, NULL, gcc_dwarf_r10_mips64, gcc_dwarf_r10_mips64, LLDB_INVALID_REGNUM, gdb_r10_mips64),
+ DEFINE_GPR(r11, NULL, gcc_dwarf_r11_mips64, gcc_dwarf_r11_mips64, LLDB_INVALID_REGNUM, gdb_r11_mips64),
+ DEFINE_GPR(r12, NULL, gcc_dwarf_r12_mips64, gcc_dwarf_r12_mips64, LLDB_INVALID_REGNUM, gdb_r12_mips64),
+ DEFINE_GPR(r13, NULL, gcc_dwarf_r13_mips64, gcc_dwarf_r13_mips64, LLDB_INVALID_REGNUM, gdb_r13_mips64),
+ DEFINE_GPR(r14, NULL, gcc_dwarf_r14_mips64, gcc_dwarf_r14_mips64, LLDB_INVALID_REGNUM, gdb_r14_mips64),
+ DEFINE_GPR(r15, NULL, gcc_dwarf_r15_mips64, gcc_dwarf_r15_mips64, LLDB_INVALID_REGNUM, gdb_r15_mips64),
+ DEFINE_GPR(r16, NULL, gcc_dwarf_r16_mips64, gcc_dwarf_r16_mips64, LLDB_INVALID_REGNUM, gdb_r16_mips64),
+ DEFINE_GPR(r17, NULL, gcc_dwarf_r17_mips64, gcc_dwarf_r17_mips64, LLDB_INVALID_REGNUM, gdb_r17_mips64),
+ DEFINE_GPR(r18, NULL, gcc_dwarf_r18_mips64, gcc_dwarf_r18_mips64, LLDB_INVALID_REGNUM, gdb_r18_mips64),
+ DEFINE_GPR(r19, NULL, gcc_dwarf_r19_mips64, gcc_dwarf_r19_mips64, LLDB_INVALID_REGNUM, gdb_r19_mips64),
+ DEFINE_GPR(r20, NULL, gcc_dwarf_r20_mips64, gcc_dwarf_r20_mips64, LLDB_INVALID_REGNUM, gdb_r20_mips64),
+ DEFINE_GPR(r21, NULL, gcc_dwarf_r21_mips64, gcc_dwarf_r21_mips64, LLDB_INVALID_REGNUM, gdb_r21_mips64),
+ DEFINE_GPR(r22, NULL, gcc_dwarf_r22_mips64, gcc_dwarf_r22_mips64, LLDB_INVALID_REGNUM, gdb_r22_mips64),
+ DEFINE_GPR(r23, NULL, gcc_dwarf_r23_mips64, gcc_dwarf_r23_mips64, LLDB_INVALID_REGNUM, gdb_r23_mips64),
+ DEFINE_GPR(r24, NULL, gcc_dwarf_r24_mips64, gcc_dwarf_r24_mips64, LLDB_INVALID_REGNUM, gdb_r24_mips64),
+ DEFINE_GPR(r25, NULL, gcc_dwarf_r25_mips64, gcc_dwarf_r25_mips64, LLDB_INVALID_REGNUM, gdb_r25_mips64),
+ DEFINE_GPR(r26, NULL, gcc_dwarf_r26_mips64, gcc_dwarf_r26_mips64, LLDB_INVALID_REGNUM, gdb_r26_mips64),
+ DEFINE_GPR(r27, NULL, gcc_dwarf_r27_mips64, gcc_dwarf_r27_mips64, LLDB_INVALID_REGNUM, gdb_r27_mips64),
+ DEFINE_GPR(gp, "r28", gcc_dwarf_gp_mips64, gcc_dwarf_gp_mips64, LLDB_INVALID_REGNUM, gdb_gp_mips64),
+ DEFINE_GPR(sp, "r29", gcc_dwarf_sp_mips64, gcc_dwarf_sp_mips64, LLDB_REGNUM_GENERIC_SP, gdb_sp_mips64),
+ DEFINE_GPR(r30, NULL, gcc_dwarf_r30_mips64, gcc_dwarf_r30_mips64, LLDB_INVALID_REGNUM, gdb_r30_mips64),
+ DEFINE_GPR(ra, "r31", gcc_dwarf_ra_mips64, gcc_dwarf_ra_mips64, LLDB_INVALID_REGNUM, gdb_ra_mips64),
+ DEFINE_GPR(sr, NULL, gcc_dwarf_sr_mips64, gcc_dwarf_sr_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(mullo, NULL, gcc_dwarf_lo_mips64, gcc_dwarf_lo_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(mulhi, NULL, gcc_dwarf_hi_mips64, gcc_dwarf_hi_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(badvaddr, NULL, gcc_dwarf_bad_mips64, gcc_dwarf_bad_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(cause, NULL, gcc_dwarf_cause_mips64, gcc_dwarf_cause_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(pc, "pc", gcc_dwarf_pc_mips64, gcc_dwarf_pc_mips64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(ic, NULL, gcc_dwarf_ic_mips64, gcc_dwarf_ic_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+ DEFINE_GPR(dummy, NULL, gcc_dwarf_dummy_mips64, gcc_dwarf_dummy_mips64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+};
+static_assert((sizeof(g_register_infos_mips64) / sizeof(g_register_infos_mips64[0])) == k_num_registers_mips64,
+ "g_register_infos_mips64 has wrong number of register infos");
+
+#undef DEFINE_GPR
+
+#endif // DECLARE_REGISTER_INFOS_MIPS64_STRUCT
+
+#undef GPR_OFFSET
+
diff --git a/source/Plugins/Process/POSIX/RegisterInfos_x86_64.h b/source/Plugins/Process/POSIX/RegisterInfos_x86_64.h
new file mode 100644
index 000000000000..1bab88cd5727
--- /dev/null
+++ b/source/Plugins/Process/POSIX/RegisterInfos_x86_64.h
@@ -0,0 +1,409 @@
+//===-- RegisterInfos_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 "llvm/Support/Compiler.h"
+
+// Computes the offset of the given GPR in the user data area.
+#define GPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(GPR, regname))
+
+// Computes the offset of the given FPR in the extended data area.
+#define FPR_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(FPR, xstate) + \
+ LLVM_EXTENSION offsetof(FXSAVE, regname))
+
+// Computes the offset of the YMM register assembled from register halves.
+#define YMM_OFFSET(regname) \
+ (LLVM_EXTENSION offsetof(YMM, regname))
+
+#ifdef DECLARE_REGISTER_INFOS_X86_64_STRUCT
+
+// Number of bytes needed to represent a FPR.
+#define FPR_SIZE(reg) sizeof(((FXSAVE*)NULL)->reg)
+
+// Number of bytes needed to represent the i'th FP register.
+#define FP_SIZE sizeof(((MMSReg*)NULL)->bytes)
+
+// Number of bytes needed to represent an XMM register.
+#define XMM_SIZE sizeof(XMMReg)
+
+// Number of bytes needed to represent a YMM register.
+#define YMM_SIZE sizeof(YMMReg)
+
+// RegisterKind: GCC, DWARF, Generic, GDB, LLDB
+
+// Note that the size and offset will be updated by platform-specific classes.
+#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \
+ { #reg, alt, sizeof(GPR::reg), GPR_OFFSET(reg), eEncodingUint, \
+ eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg##_x86_64 }, NULL, NULL }
+
+#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \
+ { #name, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \
+ eFormatHex, { kind1, kind2, kind3, kind4, fpu_##name##_x86_64 }, NULL, NULL }
+
+#define DEFINE_FP_ST(reg, i) \
+ { #reg#i, NULL, FP_SIZE, LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
+ eEncodingVector, eFormatVectorOfUInt8, \
+ { gcc_dwarf_st##i##_x86_64, gcc_dwarf_st##i##_x86_64, LLDB_INVALID_REGNUM, gdb_st##i##_x86_64, fpu_st##i##_x86_64 }, \
+ NULL, NULL }
+
+#define DEFINE_FP_MM(reg, i) \
+ { #reg#i, NULL, sizeof(uint64_t), LLVM_EXTENSION FPR_OFFSET(stmm[i]), \
+ eEncodingUint, eFormatHex, \
+ { gcc_dwarf_mm##i##_x86_64, gcc_dwarf_mm##i##_x86_64, LLDB_INVALID_REGNUM, gdb_st##i##_x86_64, fpu_mm##i##_x86_64 }, \
+ NULL, NULL }
+
+#define DEFINE_XMM(reg, i) \
+ { #reg#i, NULL, XMM_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \
+ eEncodingVector, eFormatVectorOfUInt8, \
+ { gcc_dwarf_##reg##i##_x86_64, gcc_dwarf_##reg##i##_x86_64, LLDB_INVALID_REGNUM, gdb_##reg##i##_x86_64, fpu_##reg##i##_x86_64}, \
+ NULL, NULL }
+
+#define DEFINE_YMM(reg, i) \
+ { #reg#i, NULL, YMM_SIZE, LLVM_EXTENSION YMM_OFFSET(reg[i]), \
+ eEncodingVector, eFormatVectorOfUInt8, \
+ { gcc_dwarf_##reg##i##h_x86_64, gcc_dwarf_##reg##i##h_x86_64, LLDB_INVALID_REGNUM, gdb_##reg##i##h_x86_64, fpu_##reg##i##_x86_64 }, \
+ NULL, NULL }
+
+#define DEFINE_DR(reg, i) \
+ { #reg#i, NULL, DR_SIZE, DR_OFFSET(i), eEncodingUint, eFormatHex, \
+ { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
+ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, NULL, NULL }
+
+#define DEFINE_GPR_PSEUDO_32(reg32, reg64) \
+ { #reg32, NULL, 4, GPR_OFFSET(reg64), eEncodingUint, \
+ eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_##reg32##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 }
+#define DEFINE_GPR_PSEUDO_16(reg16, reg64) \
+ { #reg16, NULL, 2, GPR_OFFSET(reg64), eEncodingUint, \
+ eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_##reg16##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 }
+#define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \
+ { #reg8, NULL, 1, GPR_OFFSET(reg64)+1, eEncodingUint, \
+ eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_##reg8##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 }
+#define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \
+ { #reg8, NULL, 1, GPR_OFFSET(reg64), eEncodingUint, \
+ eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_##reg8##_x86_64 }, RegisterContextPOSIX_x86::g_contained_##reg64, RegisterContextPOSIX_x86::g_invalidate_##reg64 }
+
+static RegisterInfo
+g_register_infos_x86_64[] =
+{
+ // General purpose registers. GCC, DWARF, Generic, GDB
+ DEFINE_GPR(rax, NULL, gcc_dwarf_rax_x86_64, gcc_dwarf_rax_x86_64, LLDB_INVALID_REGNUM, gdb_rax_x86_64),
+ DEFINE_GPR(rbx, NULL, gcc_dwarf_rbx_x86_64, gcc_dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, gdb_rbx_x86_64),
+ DEFINE_GPR(rcx, "arg4", gcc_dwarf_rcx_x86_64, gcc_dwarf_rcx_x86_64, LLDB_INVALID_REGNUM, gdb_rcx_x86_64),
+ DEFINE_GPR(rdx, "arg3", gcc_dwarf_rdx_x86_64, gcc_dwarf_rdx_x86_64, LLDB_INVALID_REGNUM, gdb_rdx_x86_64),
+ DEFINE_GPR(rdi, "arg1", gcc_dwarf_rdi_x86_64, gcc_dwarf_rdi_x86_64, LLDB_INVALID_REGNUM, gdb_rdi_x86_64),
+ DEFINE_GPR(rsi, "arg2", gcc_dwarf_rsi_x86_64, gcc_dwarf_rsi_x86_64, LLDB_INVALID_REGNUM, gdb_rsi_x86_64),
+ DEFINE_GPR(rbp, "fp", gcc_dwarf_rbp_x86_64, gcc_dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, gdb_rbp_x86_64),
+ DEFINE_GPR(rsp, "sp", gcc_dwarf_rsp_x86_64, gcc_dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, gdb_rsp_x86_64),
+ DEFINE_GPR(r8, "arg5", gcc_dwarf_r8_x86_64, gcc_dwarf_r8_x86_64, LLDB_INVALID_REGNUM, gdb_r8_x86_64),
+ DEFINE_GPR(r9, "arg6", gcc_dwarf_r9_x86_64, gcc_dwarf_r9_x86_64, LLDB_INVALID_REGNUM, gdb_r9_x86_64),
+ DEFINE_GPR(r10, NULL, gcc_dwarf_r10_x86_64, gcc_dwarf_r10_x86_64, LLDB_INVALID_REGNUM, gdb_r10_x86_64),
+ DEFINE_GPR(r11, NULL, gcc_dwarf_r11_x86_64, gcc_dwarf_r11_x86_64, LLDB_INVALID_REGNUM, gdb_r11_x86_64),
+ DEFINE_GPR(r12, NULL, gcc_dwarf_r12_x86_64, gcc_dwarf_r12_x86_64, LLDB_INVALID_REGNUM, gdb_r12_x86_64),
+ DEFINE_GPR(r13, NULL, gcc_dwarf_r13_x86_64, gcc_dwarf_r13_x86_64, LLDB_INVALID_REGNUM, gdb_r13_x86_64),
+ DEFINE_GPR(r14, NULL, gcc_dwarf_r14_x86_64, gcc_dwarf_r14_x86_64, LLDB_INVALID_REGNUM, gdb_r14_x86_64),
+ DEFINE_GPR(r15, NULL, gcc_dwarf_r15_x86_64, gcc_dwarf_r15_x86_64, LLDB_INVALID_REGNUM, gdb_r15_x86_64),
+ DEFINE_GPR(rip, "pc", gcc_dwarf_rip_x86_64, gcc_dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, gdb_rip_x86_64),
+ DEFINE_GPR(rflags, "flags", gcc_dwarf_rflags_x86_64, gcc_dwarf_rflags_x86_64, LLDB_REGNUM_GENERIC_FLAGS, gdb_rflags_x86_64),
+ DEFINE_GPR(cs, NULL, gcc_dwarf_cs_x86_64, gcc_dwarf_cs_x86_64, LLDB_INVALID_REGNUM, gdb_cs_x86_64),
+ DEFINE_GPR(fs, NULL, gcc_dwarf_fs_x86_64, gcc_dwarf_fs_x86_64, LLDB_INVALID_REGNUM, gdb_fs_x86_64),
+ DEFINE_GPR(gs, NULL, gcc_dwarf_gs_x86_64, gcc_dwarf_gs_x86_64, LLDB_INVALID_REGNUM, gdb_gs_x86_64),
+ DEFINE_GPR(ss, NULL, gcc_dwarf_ss_x86_64, gcc_dwarf_ss_x86_64, LLDB_INVALID_REGNUM, gdb_ss_x86_64),
+ DEFINE_GPR(ds, NULL, gcc_dwarf_ds_x86_64, gcc_dwarf_ds_x86_64, LLDB_INVALID_REGNUM, gdb_ds_x86_64),
+ DEFINE_GPR(es, NULL, gcc_dwarf_es_x86_64, gcc_dwarf_es_x86_64, LLDB_INVALID_REGNUM, gdb_es_x86_64),
+
+ DEFINE_GPR_PSEUDO_32(eax, rax),
+ DEFINE_GPR_PSEUDO_32(ebx, rbx),
+ DEFINE_GPR_PSEUDO_32(ecx, rcx),
+ DEFINE_GPR_PSEUDO_32(edx, rdx),
+ DEFINE_GPR_PSEUDO_32(edi, rdi),
+ DEFINE_GPR_PSEUDO_32(esi, rsi),
+ DEFINE_GPR_PSEUDO_32(ebp, rbp),
+ DEFINE_GPR_PSEUDO_32(esp, rsp),
+ DEFINE_GPR_PSEUDO_32(r8d, r8),
+ DEFINE_GPR_PSEUDO_32(r9d, r9),
+ DEFINE_GPR_PSEUDO_32(r10d, r10),
+ DEFINE_GPR_PSEUDO_32(r11d, r11),
+ DEFINE_GPR_PSEUDO_32(r12d, r12),
+ DEFINE_GPR_PSEUDO_32(r13d, r13),
+ DEFINE_GPR_PSEUDO_32(r14d, r14),
+ DEFINE_GPR_PSEUDO_32(r15d, r15),
+ DEFINE_GPR_PSEUDO_16(ax, rax),
+ DEFINE_GPR_PSEUDO_16(bx, rbx),
+ DEFINE_GPR_PSEUDO_16(cx, rcx),
+ DEFINE_GPR_PSEUDO_16(dx, rdx),
+ DEFINE_GPR_PSEUDO_16(di, rdi),
+ DEFINE_GPR_PSEUDO_16(si, rsi),
+ DEFINE_GPR_PSEUDO_16(bp, rbp),
+ DEFINE_GPR_PSEUDO_16(sp, rsp),
+ DEFINE_GPR_PSEUDO_16(r8w, r8),
+ DEFINE_GPR_PSEUDO_16(r9w, r9),
+ DEFINE_GPR_PSEUDO_16(r10w, r10),
+ DEFINE_GPR_PSEUDO_16(r11w, r11),
+ DEFINE_GPR_PSEUDO_16(r12w, r12),
+ DEFINE_GPR_PSEUDO_16(r13w, r13),
+ DEFINE_GPR_PSEUDO_16(r14w, r14),
+ DEFINE_GPR_PSEUDO_16(r15w, r15),
+ DEFINE_GPR_PSEUDO_8H(ah, rax),
+ DEFINE_GPR_PSEUDO_8H(bh, rbx),
+ DEFINE_GPR_PSEUDO_8H(ch, rcx),
+ DEFINE_GPR_PSEUDO_8H(dh, rdx),
+ DEFINE_GPR_PSEUDO_8L(al, rax),
+ DEFINE_GPR_PSEUDO_8L(bl, rbx),
+ DEFINE_GPR_PSEUDO_8L(cl, rcx),
+ DEFINE_GPR_PSEUDO_8L(dl, rdx),
+ DEFINE_GPR_PSEUDO_8L(dil, rdi),
+ DEFINE_GPR_PSEUDO_8L(sil, rsi),
+ DEFINE_GPR_PSEUDO_8L(bpl, rbp),
+ DEFINE_GPR_PSEUDO_8L(spl, rsp),
+ DEFINE_GPR_PSEUDO_8L(r8l, r8),
+ DEFINE_GPR_PSEUDO_8L(r9l, r9),
+ DEFINE_GPR_PSEUDO_8L(r10l, r10),
+ DEFINE_GPR_PSEUDO_8L(r11l, r11),
+ DEFINE_GPR_PSEUDO_8L(r12l, r12),
+ DEFINE_GPR_PSEUDO_8L(r13l, r13),
+ DEFINE_GPR_PSEUDO_8L(r14l, r14),
+ DEFINE_GPR_PSEUDO_8L(r15l, r15),
+
+ // i387 Floating point registers. GCC, DWARF, Generic, GDB
+ DEFINE_FPR(fctrl, fctrl, gcc_dwarf_fctrl_x86_64, gcc_dwarf_fctrl_x86_64, LLDB_INVALID_REGNUM, gdb_fctrl_x86_64),
+ DEFINE_FPR(fstat, fstat, gcc_dwarf_fstat_x86_64, gcc_dwarf_fstat_x86_64, LLDB_INVALID_REGNUM, gdb_fstat_x86_64),
+ DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_ftag_x86_64),
+ DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fop_x86_64),
+ DEFINE_FPR(fiseg, ptr.i386.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fiseg_x86_64),
+ DEFINE_FPR(fioff, ptr.i386.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fioff_x86_64),
+ DEFINE_FPR(foseg, ptr.i386.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_foseg_x86_64),
+ DEFINE_FPR(fooff, ptr.i386.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fooff_x86_64),
+ DEFINE_FPR(mxcsr, mxcsr, gcc_dwarf_mxcsr_x86_64, gcc_dwarf_mxcsr_x86_64, LLDB_INVALID_REGNUM, gdb_mxcsr_x86_64),
+ DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
+
+ // FP registers.
+ DEFINE_FP_ST(st, 0),
+ DEFINE_FP_ST(st, 1),
+ DEFINE_FP_ST(st, 2),
+ DEFINE_FP_ST(st, 3),
+ DEFINE_FP_ST(st, 4),
+ DEFINE_FP_ST(st, 5),
+ DEFINE_FP_ST(st, 6),
+ DEFINE_FP_ST(st, 7),
+ DEFINE_FP_MM(mm, 0),
+ DEFINE_FP_MM(mm, 1),
+ DEFINE_FP_MM(mm, 2),
+ DEFINE_FP_MM(mm, 3),
+ DEFINE_FP_MM(mm, 4),
+ DEFINE_FP_MM(mm, 5),
+ DEFINE_FP_MM(mm, 6),
+ DEFINE_FP_MM(mm, 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),
+ DEFINE_XMM(xmm, 8),
+ DEFINE_XMM(xmm, 9),
+ DEFINE_XMM(xmm, 10),
+ DEFINE_XMM(xmm, 11),
+ DEFINE_XMM(xmm, 12),
+ DEFINE_XMM(xmm, 13),
+ DEFINE_XMM(xmm, 14),
+ DEFINE_XMM(xmm, 15),
+
+ // Copy of YMM registers assembled from xmm and ymmh
+ DEFINE_YMM(ymm, 0),
+ DEFINE_YMM(ymm, 1),
+ DEFINE_YMM(ymm, 2),
+ DEFINE_YMM(ymm, 3),
+ DEFINE_YMM(ymm, 4),
+ DEFINE_YMM(ymm, 5),
+ DEFINE_YMM(ymm, 6),
+ DEFINE_YMM(ymm, 7),
+ DEFINE_YMM(ymm, 8),
+ DEFINE_YMM(ymm, 9),
+ DEFINE_YMM(ymm, 10),
+ DEFINE_YMM(ymm, 11),
+ DEFINE_YMM(ymm, 12),
+ DEFINE_YMM(ymm, 13),
+ DEFINE_YMM(ymm, 14),
+ DEFINE_YMM(ymm, 15),
+
+ // Debug registers for lldb internal use
+ DEFINE_DR(dr, 0),
+ DEFINE_DR(dr, 1),
+ DEFINE_DR(dr, 2),
+ DEFINE_DR(dr, 3),
+ DEFINE_DR(dr, 4),
+ DEFINE_DR(dr, 5),
+ DEFINE_DR(dr, 6),
+ DEFINE_DR(dr, 7)
+};
+static_assert((sizeof(g_register_infos_x86_64) / sizeof(g_register_infos_x86_64[0])) == k_num_registers_x86_64,
+ "g_register_infos_x86_64 has wrong number of register infos");
+
+#undef FPR_SIZE
+#undef FP_SIZE
+#undef XMM_SIZE
+#undef YMM_SIZE
+#undef DEFINE_GPR
+#undef DEFINE_FPR
+#undef DEFINE_FP
+#undef DEFINE_XMM
+#undef DEFINE_YMM
+#undef DEFINE_DR
+#undef DEFINE_GPR_PSEUDO_32
+#undef DEFINE_GPR_PSEUDO_16
+#undef DEFINE_GPR_PSEUDO_8H
+#undef DEFINE_GPR_PSEUDO_8L
+
+#endif // DECLARE_REGISTER_INFOS_X86_64_STRUCT
+
+
+#ifdef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
+
+#define UPDATE_GPR_INFO(reg, reg64) \
+do { \
+ g_register_infos[gpr_##reg##_i386].byte_offset = GPR_OFFSET(reg64); \
+} while(false);
+
+#define UPDATE_GPR_INFO_8H(reg, reg64) \
+do { \
+ g_register_infos[gpr_##reg##_i386].byte_offset = GPR_OFFSET(reg64) + 1; \
+} while(false);
+
+#define UPDATE_FPR_INFO(reg, reg64) \
+do { \
+ g_register_infos[fpu_##reg##_i386].byte_offset = FPR_OFFSET(reg64); \
+} while(false);
+
+#define UPDATE_FP_INFO(reg, i) \
+do { \
+ g_register_infos[fpu_##reg##i##_i386].byte_offset = FPR_OFFSET(stmm[i]); \
+} while(false);
+
+#define UPDATE_XMM_INFO(reg, i) \
+do { \
+ g_register_infos[fpu_##reg##i##_i386].byte_offset = FPR_OFFSET(reg[i]); \
+} while(false);
+
+#define UPDATE_YMM_INFO(reg, i) \
+do { \
+ g_register_infos[fpu_##reg##i##_i386].byte_offset = YMM_OFFSET(reg[i]); \
+} while(false);
+
+#define UPDATE_DR_INFO(reg_index) \
+do { \
+ g_register_infos[dr##reg_index##_i386].byte_offset = DR_OFFSET(reg_index); \
+} while(false);
+
+ // Update the register offsets
+ UPDATE_GPR_INFO(eax, rax);
+ UPDATE_GPR_INFO(ebx, rbx);
+ UPDATE_GPR_INFO(ecx, rcx);
+ UPDATE_GPR_INFO(edx, rdx);
+ UPDATE_GPR_INFO(edi, rdi);
+ UPDATE_GPR_INFO(esi, rsi);
+ UPDATE_GPR_INFO(ebp, rbp);
+ UPDATE_GPR_INFO(esp, rsp);
+ UPDATE_GPR_INFO(eip, rip);
+ UPDATE_GPR_INFO(eflags, rflags);
+ UPDATE_GPR_INFO(cs, cs);
+ UPDATE_GPR_INFO(fs, fs);
+ UPDATE_GPR_INFO(gs, gs);
+ UPDATE_GPR_INFO(ss, ss);
+ UPDATE_GPR_INFO(ds, ds);
+ UPDATE_GPR_INFO(es, es);
+
+ UPDATE_GPR_INFO(ax, rax);
+ UPDATE_GPR_INFO(bx, rbx);
+ UPDATE_GPR_INFO(cx, rcx);
+ UPDATE_GPR_INFO(dx, rdx);
+ UPDATE_GPR_INFO(di, rdi);
+ UPDATE_GPR_INFO(si, rsi);
+ UPDATE_GPR_INFO(bp, rbp);
+ UPDATE_GPR_INFO(sp, rsp);
+ UPDATE_GPR_INFO_8H(ah, rax);
+ UPDATE_GPR_INFO_8H(bh, rbx);
+ UPDATE_GPR_INFO_8H(ch, rcx);
+ UPDATE_GPR_INFO_8H(dh, rdx);
+ UPDATE_GPR_INFO(al, rax);
+ UPDATE_GPR_INFO(bl, rbx);
+ UPDATE_GPR_INFO(cl, rcx);
+ UPDATE_GPR_INFO(dl, rdx);
+
+ UPDATE_FPR_INFO(fctrl, fctrl);
+ UPDATE_FPR_INFO(fstat, fstat);
+ UPDATE_FPR_INFO(ftag, ftag);
+ UPDATE_FPR_INFO(fop, fop);
+ UPDATE_FPR_INFO(fiseg, ptr.i386.fiseg);
+ UPDATE_FPR_INFO(fioff, ptr.i386.fioff);
+ UPDATE_FPR_INFO(fooff, ptr.i386.fooff);
+ UPDATE_FPR_INFO(foseg, ptr.i386.foseg);
+ UPDATE_FPR_INFO(mxcsr, mxcsr);
+ UPDATE_FPR_INFO(mxcsrmask, mxcsrmask);
+
+ UPDATE_FP_INFO(st, 0);
+ UPDATE_FP_INFO(st, 1);
+ UPDATE_FP_INFO(st, 2);
+ UPDATE_FP_INFO(st, 3);
+ UPDATE_FP_INFO(st, 4);
+ UPDATE_FP_INFO(st, 5);
+ UPDATE_FP_INFO(st, 6);
+ UPDATE_FP_INFO(st, 7);
+ UPDATE_FP_INFO(mm, 0);
+ UPDATE_FP_INFO(mm, 1);
+ UPDATE_FP_INFO(mm, 2);
+ UPDATE_FP_INFO(mm, 3);
+ UPDATE_FP_INFO(mm, 4);
+ UPDATE_FP_INFO(mm, 5);
+ UPDATE_FP_INFO(mm, 6);
+ UPDATE_FP_INFO(mm, 7);
+
+ UPDATE_XMM_INFO(xmm, 0);
+ UPDATE_XMM_INFO(xmm, 1);
+ UPDATE_XMM_INFO(xmm, 2);
+ UPDATE_XMM_INFO(xmm, 3);
+ UPDATE_XMM_INFO(xmm, 4);
+ UPDATE_XMM_INFO(xmm, 5);
+ UPDATE_XMM_INFO(xmm, 6);
+ UPDATE_XMM_INFO(xmm, 7);
+
+ UPDATE_YMM_INFO(ymm, 0);
+ UPDATE_YMM_INFO(ymm, 1);
+ UPDATE_YMM_INFO(ymm, 2);
+ UPDATE_YMM_INFO(ymm, 3);
+ UPDATE_YMM_INFO(ymm, 4);
+ UPDATE_YMM_INFO(ymm, 5);
+ UPDATE_YMM_INFO(ymm, 6);
+ UPDATE_YMM_INFO(ymm, 7);
+
+ 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);
+
+#undef UPDATE_GPR_INFO
+#undef UPDATE_GPR_INFO_8H
+#undef UPDATE_FPR_INFO
+#undef UPDATE_FP_INFO
+#undef UPDATE_XMM_INFO
+#undef UPDATE_YMM_INFO
+#undef UPDATE_DR_INFO
+
+#endif // UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS
+
+#undef GPR_OFFSET
+#undef FPR_OFFSET
+#undef YMM_OFFSET