blob: 8f2603c3365b7439557704445b126c2a6cea0806 [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
Zachary Turner17f383d2014-11-20 22:47:32 +000019#include "ProcessWindows.h"
Adrian McCarthy3ae74922015-06-01 21:51:50 +000020#include "ProcessWindowsLog.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000021#include "TargetThreadWindows.h"
Zachary Turner17f383d2014-11-20 22:47:32 +000022#include "UnwindLLDB.h"
Zachary Turner119767d2014-11-17 17:46:43 +000023
Adrian McCarthy4ad5def2016-11-23 16:26:37 +000024#if defined(_WIN64)
Hafiz Abid Qadeer65abfb12016-11-29 09:31:57 +000025#include "x64/RegisterContextWindows_x64.h"
Adrian McCarthy4ad5def2016-11-23 16:26:37 +000026#else
27#include "x86/RegisterContextWindows_x86.h"
28#endif
29
Zachary Turner119767d2014-11-17 17:46:43 +000030using namespace lldb;
31using namespace lldb_private;
32
Kate Stoneb9c1b512016-09-06 20:57:50 +000033TargetThreadWindows::TargetThreadWindows(ProcessWindows &process,
34 const HostThread &thread)
35 : Thread(process, thread.GetNativeThread().GetThreadId()),
36 m_host_thread(thread) {}
37
38TargetThreadWindows::~TargetThreadWindows() { DestroyThread(); }
39
40void TargetThreadWindows::RefreshStateAfterStop() {
41 ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
42 SetState(eStateStopped);
43 GetRegisterContext()->InvalidateIfNeeded(false);
Zachary Turner119767d2014-11-17 17:46:43 +000044}
45
Kate Stoneb9c1b512016-09-06 20:57:50 +000046void TargetThreadWindows::WillResume(lldb::StateType resume_state) {}
47
48void TargetThreadWindows::DidStop() {}
49
Adrian McCarthy4ad5def2016-11-23 16:26:37 +000050RegisterContextSP TargetThreadWindows::GetRegisterContext() {
51 if (!m_reg_context_sp)
52 m_reg_context_sp = CreateRegisterContextForFrameIndex(0);
53
54 return m_reg_context_sp;
55}
56
57RegisterContextSP
58TargetThreadWindows::CreateRegisterContextForFrame(StackFrame *frame) {
59 return CreateRegisterContextForFrameIndex(frame->GetConcreteFrameIndex());
60}
61
62RegisterContextSP
63TargetThreadWindows::CreateRegisterContextForFrameIndex(uint32_t idx) {
64 if (!m_reg_context_sp) {
65 ArchSpec arch = HostInfo::GetArchitecture();
66 switch (arch.GetMachine()) {
67 case llvm::Triple::x86:
68#if defined(_WIN64)
69// FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64
70#else
71 m_reg_context_sp.reset(new RegisterContextWindows_x86(*this, idx));
72#endif
73 break;
74 case llvm::Triple::x86_64:
75#if defined(_WIN64)
76 m_reg_context_sp.reset(new RegisterContextWindows_x64(*this, idx));
77#else
78// LLDB is 32-bit, but the target process is 64-bit. We probably can't debug
79// this.
80#endif
81 default:
82 break;
83 }
84 }
85 return m_reg_context_sp;
86}
87
Kate Stoneb9c1b512016-09-06 20:57:50 +000088bool TargetThreadWindows::CalculateStopInfo() {
89 SetStopInfo(m_stop_info_sp);
90 return true;
Zachary Turner119767d2014-11-17 17:46:43 +000091}
92
Kate Stoneb9c1b512016-09-06 20:57:50 +000093Unwind *TargetThreadWindows::GetUnwinder() {
94 // FIXME: Implement an unwinder based on the Windows unwinder exposed through
95 // DIA SDK.
96 if (m_unwinder_ap.get() == NULL)
97 m_unwinder_ap.reset(new UnwindLLDB(*this));
98 return m_unwinder_ap.get();
Zachary Turner119767d2014-11-17 17:46:43 +000099}
100
Kate Stoneb9c1b512016-09-06 20:57:50 +0000101bool TargetThreadWindows::DoResume() {
102 StateType resume_state = GetTemporaryResumeState();
103 StateType current_state = GetState();
104 if (resume_state == current_state)
Zachary Turner17f383d2014-11-20 22:47:32 +0000105 return true;
Zachary Turner17f383d2014-11-20 22:47:32 +0000106
Kate Stoneb9c1b512016-09-06 20:57:50 +0000107 if (resume_state == eStateStepping) {
108 uint32_t flags_index =
109 GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
110 eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
111 uint64_t flags_value =
112 GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
113 flags_value |= 0x100; // Set the trap flag on the CPU
114 GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
115 }
Zachary Turner119767d2014-11-17 17:46:43 +0000116
Kate Stoneb9c1b512016-09-06 20:57:50 +0000117 if (resume_state == eStateStepping || resume_state == eStateRunning) {
118 DWORD previous_suspend_count = 0;
119 HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
120 do {
121 previous_suspend_count = ::ResumeThread(thread_handle);
122 } while (previous_suspend_count > 0);
123 }
124 return true;
Zachary Turner119767d2014-11-17 17:46:43 +0000125}