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 15 struct BreakpointManager { 16 public: 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 41 private: 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 GetKeyBreakpointManager::InstalledBreakpointSplayDefinition78 static const KeyType& GetKey(const InstalledBreakpoint* node) 79 { 80 return node->address; 81 } 82 GetLinkBreakpointManager::InstalledBreakpointSplayDefinition83 static SplayTreeLink<NodeType>* GetLink( 84 InstalledBreakpoint* node) 85 { 86 return node; 87 } 88 CompareBreakpointManager::InstalledBreakpointSplayDefinition89 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 GetListLinkBreakpointManager::InstalledBreakpointSplayDefinition97 static NodeType** GetListLink(InstalledBreakpoint* node) 98 { 99 return &node->splayNext; 100 } 101 }; 102 103 typedef IteratableSplayTree<InstalledBreakpointSplayDefinition> 104 BreakpointTree; 105 106 private: 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 134 private: 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