* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef BREAKPOINT_MANAGER_H
#define BREAKPOINT_MANAGER_H
#include <util/DoublyLinkedList.h>
#include <util/SplayTree.h>
#include <arch/user_debugger.h>
#include <lock.h>
struct BreakpointManager {
public:
BreakpointManager();
~BreakpointManager();
status_t Init();
status_t InstallBreakpoint(void* address);
status_t UninstallBreakpoint(void* address);
status_t InstallWatchpoint(void* address, uint32 type,
int32 length);
status_t UninstallWatchpoint(void* address);
void RemoveAllBreakpoints();
static bool CanAccessAddress(const void* address,
bool write);
status_t ReadMemory(const void* _address, void* _buffer,
size_t size, size_t& bytesRead);
status_t WriteMemory(void* _address, const void* _buffer,
size_t size, size_t& bytesWritten);
void PrepareToContinue(void* address);
private:
struct InstalledBreakpoint;
struct Breakpoint : DoublyLinkedListLinkImpl<Breakpoint> {
addr_t address;
InstalledBreakpoint* installedBreakpoint;
bool used;
bool software;
uint8 softwareData[
DEBUG_SOFTWARE_BREAKPOINT_SIZE];
};
typedef DoublyLinkedList<Breakpoint> BreakpointList;
struct InstalledBreakpoint : SplayTreeLink<InstalledBreakpoint> {
InstalledBreakpoint* splayNext;
Breakpoint* breakpoint;
addr_t address;
InstalledBreakpoint(addr_t address);
};
struct InstalledWatchpoint
: DoublyLinkedListLinkImpl<InstalledWatchpoint> {
addr_t address;
#if DEBUG_SHARED_BREAK_AND_WATCHPOINTS
Breakpoint* breakpoint;
#endif
};
typedef DoublyLinkedList<InstalledWatchpoint>
InstalledWatchpointList;
struct InstalledBreakpointSplayDefinition {
typedef addr_t KeyType;
typedef InstalledBreakpoint NodeType;
static const KeyType& GetKey(const InstalledBreakpoint* node)
{
return node->address;
}
static SplayTreeLink<NodeType>* GetLink(
InstalledBreakpoint* node)
{
return node;
}
static int Compare(addr_t key, const InstalledBreakpoint* node)
{
if (key < node->address)
return -1;
return key == node->address ? 0 : 1;
}
static NodeType** GetListLink(InstalledBreakpoint* node)
{
return &node->splayNext;
}
};
typedef IteratableSplayTree<InstalledBreakpointSplayDefinition>
BreakpointTree;
private:
Breakpoint* _GetUnusedHardwareBreakpoint(bool force);
status_t _InstallSoftwareBreakpoint(
InstalledBreakpoint* installed,
addr_t address);
status_t _UninstallSoftwareBreakpoint(
Breakpoint* breakpoint);
status_t _InstallHardwareBreakpoint(
Breakpoint* breakpoint, addr_t address);
status_t _UninstallHardwareBreakpoint(
Breakpoint* breakpoint);
InstalledWatchpoint* _FindWatchpoint(addr_t address) const;
status_t _InstallWatchpoint(
InstalledWatchpoint* watchpoint,
addr_t address, uint32 type, int32 length);
status_t _UninstallWatchpoint(
InstalledWatchpoint* watchpoint);
status_t _ReadMemory(const addr_t _address,
void* _buffer, size_t size,
size_t& bytesRead);
status_t _WriteMemory(addr_t _address,
const void* _buffer, size_t size,
size_t& bytesWritten);
private:
rw_lock fLock;
BreakpointList fHardwareBreakpoints;
BreakpointTree fBreakpoints;
InstalledWatchpointList fWatchpoints;
int32 fBreakpointCount;
int32 fWatchpointCount;
};
#endif