blob: e849a920cd0bef00f345f7c3774b62560e3b3441 [file] [log] [blame]
Zachary Turner119767d2014-11-17 17:46:43 +00001//===-- TargetThreadWindows.cpp----------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Adrian McCarthy3ae74922015-06-01 21:51:50 +000010#include "lldb/Core/Log.h"
11#include "lldb/Core/Logging.h"
12#include "lldb/Core/State.h"
Zachary Turner17f383d2014-11-20 22:47:32 +000013#include "lldb/Host/HostInfo.h"
Zachary Turner119767d2014-11-17 17:46:43 +000014#include "lldb/Host/HostNativeThreadBase.h"
15#include "lldb/Host/windows/HostThreadWindows.h"
16#include "lldb/Host/windows/windows.h"
Zachary Turner17f383d2014-11-20 22:47:32 +000017#include "lldb/Target/RegisterContext.h"
18
19#include "TargetThreadWindows.h"
20#include "ProcessWindows.h"
Adrian McCarthy3ae74922015-06-01 21:51:50 +000021#include "ProcessWindowsLog.h"
Zachary Turner17f383d2014-11-20 22:47:32 +000022#include "UnwindLLDB.h"
Zachary Turner119767d2014-11-17 17:46:43 +000023
Zachary Turner7cc34942015-04-27 22:58:57 +000024#if defined(_WIN64)
25#include "x64/RegisterContextWindows_x64.h"
26#else
Zachary Turner7ae4b6d2014-12-18 18:21:33 +000027#include "x86/RegisterContextWindows_x86.h"
28#endif
29
Zachary Turner119767d2014-11-17 17:46:43 +000030using namespace lldb;
31using namespace lldb_private;
32
33TargetThreadWindows::TargetThreadWindows(ProcessWindows &process, const HostThread &thread)
Zachary Turnerc3018992014-11-17 22:42:57 +000034 : Thread(process, thread.GetNativeThread().GetThreadId())
Zachary Turner119767d2014-11-17 17:46:43 +000035 , m_host_thread(thread)
36{
37}
38
39TargetThreadWindows::~TargetThreadWindows()
40{
41 DestroyThread();
42}
43
44void
45TargetThreadWindows::RefreshStateAfterStop()
46{
Zachary Turner48b475c2015-04-02 20:57:38 +000047 ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
Adrian McCarthy3ae74922015-06-01 21:51:50 +000048 SetState(eStateStopped);
Zachary Turner17f383d2014-11-20 22:47:32 +000049 GetRegisterContext()->InvalidateIfNeeded(false);
Zachary Turner119767d2014-11-17 17:46:43 +000050}
51
52void
53TargetThreadWindows::WillResume(lldb::StateType resume_state)
54{
55}
56
57void
58TargetThreadWindows::DidStop()
59{
60}
61
62RegisterContextSP
63TargetThreadWindows::GetRegisterContext()
64{
Zachary Turner17f383d2014-11-20 22:47:32 +000065 if (!m_reg_context_sp)
66 m_reg_context_sp = CreateRegisterContextForFrameIndex(0);
67
68 return m_reg_context_sp;
Zachary Turner119767d2014-11-17 17:46:43 +000069}
70
71RegisterContextSP
72TargetThreadWindows::CreateRegisterContextForFrame(StackFrame *frame)
73{
Zachary Turner17f383d2014-11-20 22:47:32 +000074 return CreateRegisterContextForFrameIndex(frame->GetConcreteFrameIndex());
75}
76
77RegisterContextSP
78TargetThreadWindows::CreateRegisterContextForFrameIndex(uint32_t idx)
79{
80 if (!m_reg_context_sp)
81 {
82 ArchSpec arch = HostInfo::GetArchitecture();
83 switch (arch.GetMachine())
84 {
85 case llvm::Triple::x86:
Zachary Turner7ae4b6d2014-12-18 18:21:33 +000086#if defined(_WIN64)
87 // FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64
88#else
Zachary Turner17f383d2014-11-20 22:47:32 +000089 m_reg_context_sp.reset(new RegisterContextWindows_x86(*this, idx));
Zachary Turner7ae4b6d2014-12-18 18:21:33 +000090#endif
Zachary Turner17f383d2014-11-20 22:47:32 +000091 break;
Zachary Turner7ae4b6d2014-12-18 18:21:33 +000092 case llvm::Triple::x86_64:
93#if defined(_WIN64)
Zachary Turner7cc34942015-04-27 22:58:57 +000094 m_reg_context_sp.reset(new RegisterContextWindows_x64(*this, idx));
Zachary Turner7ae4b6d2014-12-18 18:21:33 +000095#else
96 // LLDB is 32-bit, but the target process is 64-bit. We probably can't debug this.
97#endif
Zachary Turner17f383d2014-11-20 22:47:32 +000098 default:
Zachary Turner17f383d2014-11-20 22:47:32 +000099 break;
100 }
101 }
102 return m_reg_context_sp;
Zachary Turner119767d2014-11-17 17:46:43 +0000103}
104
105bool
106TargetThreadWindows::CalculateStopInfo()
107{
Zachary Turner17f383d2014-11-20 22:47:32 +0000108 SetStopInfo(m_stop_info_sp);
109 return true;
110}
111
112Unwind *
113TargetThreadWindows::GetUnwinder()
114{
115 // FIXME: Implement an unwinder based on the Windows unwinder exposed through DIA SDK.
116 if (m_unwinder_ap.get() == NULL)
117 m_unwinder_ap.reset(new UnwindLLDB(*this));
118 return m_unwinder_ap.get();
Zachary Turner119767d2014-11-17 17:46:43 +0000119}
120
121bool
122TargetThreadWindows::DoResume()
123{
Adrian McCarthy5cbef0e2015-07-06 17:42:09 +0000124 StateType resume_state = GetTemporaryResumeState();
Zachary Turner119767d2014-11-17 17:46:43 +0000125 StateType current_state = GetState();
126 if (resume_state == current_state)
127 return true;
128
Zachary Turnerf194c502015-01-15 22:54:08 +0000129 if (resume_state == eStateStepping)
Zachary Turner119767d2014-11-17 17:46:43 +0000130 {
Zachary Turnerf194c502015-01-15 22:54:08 +0000131 uint32_t flags_index = GetRegisterContext()->ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
132 uint64_t flags_value = GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
133 flags_value |= 0x100; // Set the trap flag on the CPU
134 GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
Zachary Turner119767d2014-11-17 17:46:43 +0000135 }
Zachary Turnerf194c502015-01-15 22:54:08 +0000136
137 if (resume_state == eStateStepping || resume_state == eStateRunning)
138 {
139 DWORD previous_suspend_count = 0;
140 HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
141 do
142 {
143 previous_suspend_count = ::ResumeThread(thread_handle);
144 } while (previous_suspend_count > 0);
145 }
146 return true;
Zachary Turner119767d2014-11-17 17:46:43 +0000147}