1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef BREAKPOINT_MANAGER_H
6#define BREAKPOINT_MANAGER_H
7
8#include <util/DoublyLinkedList.h>
9#include <util/SplayTree.h>
10
11#include <arch/user_debugger.h>
12#include <lock.h>
13
14
15struct BreakpointManager {
16public:
17								BreakpointManager();
18								~BreakpointManager();
19
20			status_t			Init();
21
22			status_t			InstallBreakpoint(void* address);
23			status_t			UninstallBreakpoint(void* address);
24
25			status_t			InstallWatchpoint(void* address, uint32 type,
26									int32 length);
27			status_t			UninstallWatchpoint(void* address);
28
29			void				RemoveAllBreakpoints();
30									// break- and watchpoints
31
32	static	bool				CanAccessAddress(const void* address,
33									bool write);
34			status_t			ReadMemory(const void* _address, void* _buffer,
35									size_t size, size_t& bytesRead);
36			status_t			WriteMemory(void* _address, const void* _buffer,
37									size_t size, size_t& bytesWritten);
38
39			void				PrepareToContinue(void* address);
40
41private:
42			struct InstalledBreakpoint;
43
44			struct Breakpoint : DoublyLinkedListLinkImpl<Breakpoint> {
45				addr_t					address;
46				InstalledBreakpoint*	installedBreakpoint;
47				bool					used;
48				bool					software;
49				uint8					softwareData[
50											DEBUG_SOFTWARE_BREAKPOINT_SIZE];
51			};
52
53			typedef DoublyLinkedList<Breakpoint> BreakpointList;
54
55			struct InstalledBreakpoint : SplayTreeLink<InstalledBreakpoint> {
56				InstalledBreakpoint*	splayNext;
57				Breakpoint*				breakpoint;
58				addr_t					address;
59
60				InstalledBreakpoint(addr_t address);
61			};
62
63			struct InstalledWatchpoint
64					: DoublyLinkedListLinkImpl<InstalledWatchpoint> {
65				addr_t					address;
66#if DEBUG_SHARED_BREAK_AND_WATCHPOINTS
67				Breakpoint*				breakpoint;
68#endif
69			};
70
71			typedef DoublyLinkedList<InstalledWatchpoint>
72				InstalledWatchpointList;
73
74			struct InstalledBreakpointSplayDefinition {
75				typedef addr_t				KeyType;
76				typedef	InstalledBreakpoint	NodeType;
77
78				static const KeyType& GetKey(const InstalledBreakpoint* node)
79				{
80					return node->address;
81				}
82
83				static SplayTreeLink<NodeType>* GetLink(
84					InstalledBreakpoint* node)
85				{
86					return node;
87				}
88
89				static int Compare(addr_t key, const InstalledBreakpoint* node)
90				{
91					if (key < node->address)
92						return -1;
93					return key == node->address ? 0 : 1;
94				}
95
96				// for IteratableSplayTree only
97				static NodeType** GetListLink(InstalledBreakpoint* node)
98				{
99					return &node->splayNext;
100				}
101			};
102
103			typedef IteratableSplayTree<InstalledBreakpointSplayDefinition>
104				BreakpointTree;
105
106private:
107			Breakpoint*			_GetUnusedHardwareBreakpoint(bool force);
108
109			status_t			_InstallSoftwareBreakpoint(
110									InstalledBreakpoint* installed,
111									addr_t address);
112			status_t			_UninstallSoftwareBreakpoint(
113									Breakpoint* breakpoint);
114
115			status_t			_InstallHardwareBreakpoint(
116									Breakpoint* breakpoint, addr_t address);
117			status_t			_UninstallHardwareBreakpoint(
118									Breakpoint* breakpoint);
119
120			InstalledWatchpoint* _FindWatchpoint(addr_t address) const;
121			status_t			_InstallWatchpoint(
122									InstalledWatchpoint* watchpoint,
123									addr_t address, uint32 type, int32 length);
124			status_t			_UninstallWatchpoint(
125									InstalledWatchpoint* watchpoint);
126
127			status_t			_ReadMemory(const addr_t _address,
128									void* _buffer, size_t size,
129									size_t& bytesRead);
130			status_t			_WriteMemory(addr_t _address,
131									const void* _buffer, size_t size,
132									size_t& bytesWritten);
133
134private:
135			rw_lock				fLock;
136			BreakpointList		fHardwareBreakpoints;
137			BreakpointTree		fBreakpoints;
138			InstalledWatchpointList fWatchpoints;
139			int32				fBreakpointCount;
140			int32				fWatchpointCount;
141};
142
143
144#endif	// BREAKPOINT_MANAGER_H
145