DebugServer2
Loading...
Searching...
No Matches
Thread.h
1//
2// Copyright (c) 2014-present, Facebook, Inc.
3// All rights reserved.
4//
5// This source code is licensed under the University of Illinois/NCSA Open
6// Source License found in the LICENSE file in the root directory of this
7// source tree. An additional grant of patent rights can be found in the
8// PATENTS file in the same directory.
9//
10
11#pragma once
12
13#include "DebugServer2/Target/ThreadBase.h"
14
15#include <vector>
16
17namespace ds2 {
18namespace Target {
19namespace Windows {
20
22protected:
23 HANDLE _handle;
24
25protected:
26 friend class Process;
27 Thread(Process *process, ThreadId tid, HANDLE handle);
28
29public:
30 virtual ~Thread();
31
32public:
33 virtual ErrorCode terminate() override;
34
35public:
36 virtual ErrorCode suspend() override;
37
38public:
39 virtual ErrorCode step(int signal = 0,
40 Address const &address = Address()) override;
41 virtual ErrorCode resume(int signal = 0,
42 Address const &address = Address()) override;
43
44public:
45 virtual ErrorCode afterResume();
46
47public:
48 virtual ErrorCode readCPUState(Architecture::CPUState &state) override;
49 virtual ErrorCode writeCPUState(Architecture::CPUState const &state) override;
50
51public:
52 // The ExceptionCode from the most recent EXCEPTION_DEBUG_EVENT delivered
53 // to this thread. On ARM64, there is no equivalent of x86's DR6 status
54 // register to ask "did a debug register actually cause this stop", so
55 // Sources/Core/Windows/ARM64/HardwareBreakpointManager.cpp's hit() uses
56 // this (together with wasExplicitStep(), see below) as the next best
57 // signal to rule out stops that cannot possibly be a watchpoint.
58 DWORD lastExceptionCode() const { return _lastExceptionCode; }
59
60#if defined(ARCH_ARM64)
61public:
62 // Reads/writes the hardware watchpoint value/control register pairs
63 // (Wvr[]/Wcr[] in CONTEXT_DEBUG_REGISTERS). `addresses`/`controls` are
64 // always sized to ARM64_MAX_WATCHPOINTS worth of entries by
65 // readWatchpointRegisters().
66 ErrorCode readWatchpointRegisters(std::vector<uint64_t> &addresses,
67 std::vector<uint32_t> &controls);
68 ErrorCode
69 writeWatchpointRegisters(std::vector<uint64_t> const &addresses,
70 std::vector<uint32_t> const &controls);
71
72public:
73 // PSTATE.SS, per the ARMv8 architecture reference manual. Thread::step()
74 // sets this bit before resuming to arm a single hardware step; the
75 // architectural software-step exception transition clears it again
76 // before the stopped context can be read (precisely so stepping does not
77 // recursively re-trap), so it is not usable after the fact to tell
78 // whether a stop was the completion of that step. Thread::afterResume()
79 // also clears it, for the ordinary case where the step exception is
80 // never taken (e.g. a breakpoint hit first).
81 static constexpr uint64_t kPSTATE_SS = 1ULL << 21;
82
83public:
84 // Set by Thread::step() before it resumes with PSTATE.SS to arm a
85 // hardware single step. updateState(DEBUG_EVENT const&) captures this
86 // (and resets it) into wasExplicitStep() for the resulting stop, since
87 // PSTATE.SS itself cannot be used for that (see above): this is the
88 // ground truth for whether a STATUS_SINGLE_STEP is the expected
89 // completion of a step this side requested, as opposed to an unrelated
90 // watchpoint firing.
91 void setExplicitStep() { _explicitStep = true; }
92 bool wasExplicitStep() const { return _wasExplicitStep; }
93#endif
94
95private:
96 DWORD _lastExceptionCode = 0;
97#if defined(ARCH_ARM64)
98 bool _explicitStep = false;
99 bool _wasExplicitStep = false;
100#endif
101
102protected:
103 virtual void updateState() override;
104 virtual void updateState(DEBUG_EVENT const &de);
105};
106} // namespace Windows
107} // namespace Target
108} // namespace ds2
Definition Types.h:96
Definition ThreadBase.h:22
Definition Process.h:21
Definition Thread.h:21