blob: e358062534afe4facdb548041b49d84addb5e955 [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
Zachary Turner17f383d2014-11-20 22:47:32 +000010#include "lldb/Host/HostInfo.h"
Zachary Turner119767d2014-11-17 17:46:43 +000011#include "lldb/Host/HostNativeThreadBase.h"
12#include "lldb/Host/windows/HostThreadWindows.h"
13#include "lldb/Host/windows/windows.h"
Zachary Turner17f383d2014-11-20 22:47:32 +000014#include "lldb/Target/RegisterContext.h"
15
16#include "TargetThreadWindows.h"
17#include "ProcessWindows.h"
Zachary Turner17f383d2014-11-20 22:47:32 +000018#include "UnwindLLDB.h"
Zachary Turner119767d2014-11-17 17:46:43 +000019
Zachary Turner7cc34942015-04-27 22:58:57 +000020#if defined(_WIN64)
21#include "x64/RegisterContextWindows_x64.h"
22#else
Zachary Turner7ae4b6d2014-12-18 18:21:33 +000023#include "x86/RegisterContextWindows_x86.h"
24#endif
25
Zachary Turner119767d2014-11-17 17:46:43 +000026using namespace lldb;
27using namespace lldb_private;
28
29TargetThreadWindows::TargetThreadWindows(ProcessWindows &process, const HostThread &thread)
Zachary Turnerc3018992014-11-17 22:42:57 +000030 : Thread(process, thread.GetNativeThread().GetThreadId())
Zachary Turner119767d2014-11-17 17:46:43 +000031 , m_host_thread(thread)
32{
33}
34
35TargetThreadWindows::~TargetThreadWindows()
36{
37 DestroyThread();
38}
39
40void
41TargetThreadWindows::RefreshStateAfterStop()
42{
Zachary Turner48b475c2015-04-02 20:57:38 +000043 ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
Zachary Turnerf194c502015-01-15 22:54:08 +000044
Zachary Turner17f383d2014-11-20 22:47:32 +000045 GetRegisterContext()->InvalidateIfNeeded(false);
Zachary Turner119767d2014-11-17 17:46:43 +000046}
47
48void
49TargetThreadWindows::WillResume(lldb::StateType resume_state)
50{
Zachary Turnerf194c502015-01-15 22:54:08 +000051 SetResumeState(resume_state);
Zachary Turner119767d2014-11-17 17:46:43 +000052}
53
54void
55TargetThreadWindows::DidStop()
56{
57}
58
59RegisterContextSP
60TargetThreadWindows::GetRegisterContext()
61{
Zachary Turner17f383d2014-11-20 22:47:32 +000062 if (!m_reg_context_sp)
63 m_reg_context_sp = CreateRegisterContextForFrameIndex(0);
64
65 return m_reg_context_sp;
Zachary Turner119767d2014-11-17 17:46:43 +000066}
67
68RegisterContextSP
69TargetThreadWindows::CreateRegisterContextForFrame(StackFrame *frame)
70{
Zachary Turner17f383d2014-11-20 22:47:32 +000071 return CreateRegisterContextForFrameIndex(frame->GetConcreteFrameIndex());
72}
73
74RegisterContextSP
75TargetThreadWindows::CreateRegisterContextForFrameIndex(uint32_t idx)
76{
77 if (!m_reg_context_sp)
78 {
79 ArchSpec arch = HostInfo::GetArchitecture();
80 switch (arch.GetMachine())
81 {
82 case llvm::Triple::x86:
Zachary Turner7ae4b6d2014-12-18 18:21:33 +000083#if defined(_WIN64)
84 // FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64
85#else
Zachary Turner17f383d2014-11-20 22:47:32 +000086 m_reg_context_sp.reset(new RegisterContextWindows_x86(*this, idx));
Zachary Turner7ae4b6d2014-12-18 18:21:33 +000087#endif
Zachary Turner17f383d2014-11-20 22:47:32 +000088 break;
Zachary Turner7ae4b6d2014-12-18 18:21:33 +000089 case llvm::Triple::x86_64:
90#if defined(_WIN64)
Zachary Turner7cc34942015-04-27 22:58:57 +000091 m_reg_context_sp.reset(new RegisterContextWindows_x64(*this, idx));
Zachary Turner7ae4b6d2014-12-18 18:21:33 +000092#else
93 // LLDB is 32-bit, but the target process is 64-bit. We probably can't debug this.
94#endif
Zachary Turner17f383d2014-11-20 22:47:32 +000095 default:
Zachary Turner17f383d2014-11-20 22:47:32 +000096 break;
97 }
98 }
99 return m_reg_context_sp;
Zachary Turner119767d2014-11-17 17:46:43 +0000100}
101
102bool
103TargetThreadWindows::CalculateStopInfo()
104{
Zachary Turner17f383d2014-11-20 22:47:32 +0000105 SetStopInfo(m_stop_info_sp);
106 return true;
107}
108
109Unwind *
110TargetThreadWindows::GetUnwinder()
111{
112 // FIXME: Implement an unwinder based on the Windows unwinder exposed through DIA SDK.
113 if (m_unwinder_ap.get() == NULL)
114 m_unwinder_ap.reset(new UnwindLLDB(*this));
115 return m_unwinder_ap.get();
Zachary Turner119767d2014-11-17 17:46:43 +0000116}
117
118bool
119TargetThreadWindows::DoResume()
120{
121 StateType resume_state = GetResumeState();
122 StateType current_state = GetState();
123 if (resume_state == current_state)
124 return true;
125
Zachary Turnerf194c502015-01-15 22:54:08 +0000126 if (resume_state == eStateStepping)
Zachary Turner119767d2014-11-17 17:46:43 +0000127 {
Zachary Turnerf194c502015-01-15 22:54:08 +0000128 uint32_t flags_index = GetRegisterContext()->ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
129 uint64_t flags_value = GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
130 flags_value |= 0x100; // Set the trap flag on the CPU
131 GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
Zachary Turner119767d2014-11-17 17:46:43 +0000132 }
Zachary Turnerf194c502015-01-15 22:54:08 +0000133
134 if (resume_state == eStateStepping || resume_state == eStateRunning)
135 {
136 DWORD previous_suspend_count = 0;
137 HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
138 do
139 {
140 previous_suspend_count = ::ResumeThread(thread_handle);
141 } while (previous_suspend_count > 0);
142 }
143 return true;
Zachary Turner119767d2014-11-17 17:46:43 +0000144}