aboutsummaryrefslogtreecommitdiff
path: root/source/Plugins/Process/POSIX/POSIXThread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/Process/POSIX/POSIXThread.cpp')
-rw-r--r--source/Plugins/Process/POSIX/POSIXThread.cpp156
1 files changed, 101 insertions, 55 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: