diff options
Diffstat (limited to 'source/Plugins/Process/POSIX/POSIXThread.cpp')
-rw-r--r-- | source/Plugins/Process/POSIX/POSIXThread.cpp | 156 |
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: |