1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
//===-- TargetThreadWindowsLive.cpp------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lldb/Core/Log.h"
#include "lldb/Core/Logging.h"
#include "lldb/Core/State.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/HostNativeThreadBase.h"
#include "lldb/Host/windows/HostThreadWindows.h"
#include "lldb/Host/windows/windows.h"
#include "lldb/Target/RegisterContext.h"
#include "TargetThreadWindowsLive.h"
#include "ProcessWindows.h"
#include "ProcessWindowsLog.h"
#include "UnwindLLDB.h"
#if defined(_WIN64)
#include "x64/RegisterContextWindowsLive_x64.h"
#else
#include "x86/RegisterContextWindowsLive_x86.h"
#endif
using namespace lldb;
using namespace lldb_private;
TargetThreadWindowsLive::TargetThreadWindowsLive(ProcessWindows &process, const HostThread &thread)
: TargetThreadWindows(process, thread)
, m_host_thread(thread)
{
}
TargetThreadWindowsLive::~TargetThreadWindowsLive()
{
DestroyThread();
}
void
TargetThreadWindowsLive::RefreshStateAfterStop()
{
::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
SetState(eStateStopped);
GetRegisterContext()->InvalidateIfNeeded(false);
}
void
TargetThreadWindowsLive::WillResume(lldb::StateType resume_state)
{
}
void
TargetThreadWindowsLive::DidStop()
{
}
RegisterContextSP
TargetThreadWindowsLive::GetRegisterContext()
{
if (!m_reg_context_sp)
m_reg_context_sp = CreateRegisterContextForFrameIndex(0);
return m_reg_context_sp;
}
RegisterContextSP
TargetThreadWindowsLive::CreateRegisterContextForFrame(StackFrame *frame)
{
return CreateRegisterContextForFrameIndex(frame->GetConcreteFrameIndex());
}
RegisterContextSP
TargetThreadWindowsLive::CreateRegisterContextForFrameIndex(uint32_t idx)
{
if (!m_reg_context_sp)
{
ArchSpec arch = HostInfo::GetArchitecture();
switch (arch.GetMachine())
{
case llvm::Triple::x86:
#if defined(_WIN64)
// FIXME: This is a Wow64 process, create a RegisterContextWindows_Wow64
#else
m_reg_context_sp.reset(new RegisterContextWindowsLive_x86(*this, idx));
#endif
break;
case llvm::Triple::x86_64:
#if defined(_WIN64)
m_reg_context_sp.reset(new RegisterContextWindowsLive_x64(*this, idx));
#else
// LLDB is 32-bit, but the target process is 64-bit. We probably can't debug this.
#endif
default:
break;
}
}
return m_reg_context_sp;
}
bool
TargetThreadWindowsLive::CalculateStopInfo()
{
SetStopInfo(m_stop_info_sp);
return true;
}
Unwind *
TargetThreadWindowsLive::GetUnwinder()
{
// FIXME: Implement an unwinder based on the Windows unwinder exposed through DIA SDK.
if (m_unwinder_ap.get() == NULL)
m_unwinder_ap.reset(new UnwindLLDB(*this));
return m_unwinder_ap.get();
}
bool
TargetThreadWindowsLive::DoResume()
{
StateType resume_state = GetTemporaryResumeState();
StateType current_state = GetState();
if (resume_state == current_state)
return true;
if (resume_state == eStateStepping)
{
uint32_t flags_index = GetRegisterContext()->ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
uint64_t flags_value = GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
flags_value |= 0x100; // Set the trap flag on the CPU
GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
}
if (resume_state == eStateStepping || resume_state == eStateRunning)
{
DWORD previous_suspend_count = 0;
HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
do
{
previous_suspend_count = ::ResumeThread(thread_handle);
} while (previous_suspend_count > 0);
}
return true;
}
|