| //===-- ThreadMemory.cpp ----------------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "Plugins/Process/Utility/ThreadMemory.h" |
| #include "lldb/Target/OperatingSystem.h" |
| #include "lldb/Target/RegisterContext.h" |
| #include "lldb/Target/Process.h" |
| #include "lldb/Target/StopInfo.h" |
| #include "lldb/Target/Unwind.h" |
| #include "Plugins/Process/Utility/RegisterContextThreadMemory.h" |
| |
| using namespace lldb; |
| using namespace lldb_private; |
| |
| ThreadMemory::ThreadMemory (Process &process, |
| tid_t tid, |
| const ValueObjectSP &thread_info_valobj_sp) : |
| Thread (process, tid), |
| m_backing_thread_sp (), |
| m_thread_info_valobj_sp (thread_info_valobj_sp), |
| m_name(), |
| m_queue() |
| { |
| } |
| |
| |
| ThreadMemory::ThreadMemory (Process &process, |
| lldb::tid_t tid, |
| const char *name, |
| const char *queue, |
| lldb::addr_t register_data_addr) : |
| Thread (process, tid), |
| m_backing_thread_sp (), |
| m_thread_info_valobj_sp (), |
| m_name(), |
| m_queue(), |
| m_register_data_addr (register_data_addr) |
| { |
| if (name) |
| m_name = name; |
| if (queue) |
| m_queue = queue; |
| } |
| |
| |
| ThreadMemory::~ThreadMemory() |
| { |
| DestroyThread(); |
| } |
| |
| void |
| ThreadMemory::WillResume (StateType resume_state) |
| { |
| if (m_backing_thread_sp) |
| m_backing_thread_sp->WillResume(resume_state); |
| } |
| |
| void |
| ThreadMemory::ClearStackFrames () |
| { |
| if (m_backing_thread_sp) |
| m_backing_thread_sp->ClearStackFrames(); |
| Thread::ClearStackFrames(); |
| } |
| |
| RegisterContextSP |
| ThreadMemory::GetRegisterContext () |
| { |
| if (!m_reg_context_sp) |
| m_reg_context_sp.reset (new RegisterContextThreadMemory (*this, m_register_data_addr)); |
| return m_reg_context_sp; |
| } |
| |
| RegisterContextSP |
| ThreadMemory::CreateRegisterContextForFrame (StackFrame *frame) |
| { |
| RegisterContextSP reg_ctx_sp; |
| uint32_t concrete_frame_idx = 0; |
| |
| if (frame) |
| concrete_frame_idx = frame->GetConcreteFrameIndex (); |
| |
| if (concrete_frame_idx == 0) |
| { |
| reg_ctx_sp = GetRegisterContext (); |
| } |
| else |
| { |
| Unwind *unwinder = GetUnwinder (); |
| if (unwinder) |
| reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame); |
| } |
| return reg_ctx_sp; |
| } |
| |
| bool |
| ThreadMemory::CalculateStopInfo () |
| { |
| if (m_backing_thread_sp) |
| { |
| lldb::StopInfoSP backing_stop_info_sp (m_backing_thread_sp->GetPrivateStopInfo()); |
| if (backing_stop_info_sp) |
| { |
| backing_stop_info_sp->SetThread (shared_from_this()); |
| SetStopInfo (backing_stop_info_sp); |
| return true; |
| } |
| } |
| else |
| { |
| ProcessSP process_sp (GetProcess()); |
| |
| if (process_sp) |
| { |
| OperatingSystem *os = process_sp->GetOperatingSystem (); |
| if (os) |
| { |
| SetStopInfo (os->CreateThreadStopReason (this)); |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| void |
| ThreadMemory::RefreshStateAfterStop() |
| { |
| if (m_backing_thread_sp) |
| return m_backing_thread_sp->RefreshStateAfterStop(); |
| |
| if (m_reg_context_sp) |
| m_reg_context_sp->InvalidateAllRegisters(); |
| } |