aboutsummaryrefslogtreecommitdiff
path: root/src/core/debugger/debugger_interface.h
blob: d48dd892daf802c04ca5333258a2a5bcef896d43 (plain) (blame)
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
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later

// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include <functional>
#include <span>
#include <vector>

#include "common/common_types.h"

namespace Kernel {
class KThread;
struct DebugWatchpoint;
} // namespace Kernel

namespace Core {

enum class DebuggerAction {
    Interrupt,         ///< Stop emulation as soon as possible.
    Continue,          ///< Resume emulation.
    ContinueThreads,   ///< Resume only specific threads (listed in frontend).
    StepThread,        ///< Step the active thread and resume only threads listed in frontend.
    ShutdownEmulation, ///< Shut down the emulator.
};

class DebuggerBackend {
public:
    virtual ~DebuggerBackend() = default;

    /// Can be invoked from a callback to synchronously wait for more data.
    /// Will return as soon as least one byte is received. Reads up to 4096 bytes.
    virtual std::span<const u8> ReadFromClient() = 0;

    /// Can be invoked from a callback to write data to the client.
    /// Returns immediately after the data is sent.
    virtual void WriteToClient(std::span<const u8> data) = 0;

    /// Gets the currently active thread when the debugger is stopped.
    virtual Kernel::KThread* GetActiveThread() = 0;

    /// Sets the currently active thread when the debugger is stopped.
    virtual void SetActiveThread(Kernel::KThread* thread) = 0;
};

class DebuggerFrontend {
public:
    explicit DebuggerFrontend(DebuggerBackend& backend_) : backend{backend_} {}

    virtual ~DebuggerFrontend() = default;

    /// Called after the client has successfully connected to the port.
    virtual void Connected() = 0;

    /// Called when emulation has stopped.
    virtual void Stopped(Kernel::KThread* thread) = 0;

    /// Called when emulation is shutting down.
    virtual void ShuttingDown() = 0;

    /// Called when emulation has stopped on a watchpoint.
    virtual void Watchpoint(Kernel::KThread* thread, const Kernel::DebugWatchpoint& watch) = 0;

    /// Called when new data is asynchronously received on the client socket.
    /// A list of actions to perform is returned.
    [[nodiscard]] virtual std::vector<DebuggerAction> ClientData(std::span<const u8> data) = 0;

protected:
    DebuggerBackend& backend;
};

} // namespace Core