1/*
2 * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2012, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
5 */
6
7#include "WatchpointManager.h"
8
9#include <stdio.h>
10
11#include <new>
12
13#include <AutoLocker.h>
14
15#include "DebuggerInterface.h"
16#include "Team.h"
17#include "Tracing.h"
18
19
20WatchpointManager::WatchpointManager(Team* team,
21	DebuggerInterface* debuggerInterface)
22	:
23	fLock("watchpoint manager"),
24	fTeam(team),
25	fDebuggerInterface(debuggerInterface)
26{
27	fDebuggerInterface->AcquireReference();
28}
29
30
31WatchpointManager::~WatchpointManager()
32{
33	fDebuggerInterface->ReleaseReference();
34}
35
36
37status_t
38WatchpointManager::Init()
39{
40	return fLock.InitCheck();
41}
42
43
44status_t
45WatchpointManager::InstallWatchpoint(Watchpoint* watchpoint,
46	bool enabled)
47{
48	status_t error = B_OK;
49	TRACE_CONTROL("WatchpointManager::InstallUserWatchpoint(%p, %d)\n",
50		watchpoint, enabled);
51
52	AutoLocker<BLocker> installLocker(fLock);
53	AutoLocker<Team> teamLocker(fTeam);
54
55	bool oldEnabled = watchpoint->IsEnabled();
56	if (enabled == oldEnabled) {
57		TRACE_CONTROL("  watchpoint already valid and with same enabled "
58			"state\n");
59		return B_OK;
60	}
61
62	watchpoint->SetEnabled(enabled);
63
64	if (watchpoint->ShouldBeInstalled()) {
65		error = fDebuggerInterface->InstallWatchpoint(watchpoint->Address(),
66			watchpoint->Type(), watchpoint->Length());
67
68		if (error == B_OK)
69			watchpoint->SetInstalled(true);
70	} else {
71		error = fDebuggerInterface->UninstallWatchpoint(watchpoint->Address());
72
73		if (error == B_OK)
74			watchpoint->SetInstalled(false);
75	}
76
77	if (error == B_OK) {
78		if (fTeam->WatchpointAtAddress(watchpoint->Address()) == NULL)
79			fTeam->AddWatchpoint(watchpoint);
80		fTeam->NotifyWatchpointChanged(watchpoint);
81	}
82
83	return error;
84}
85
86
87void
88WatchpointManager::UninstallWatchpoint(Watchpoint* watchpoint)
89{
90	AutoLocker<BLocker> installLocker(fLock);
91	AutoLocker<Team> teamLocker(fTeam);
92
93	fTeam->RemoveWatchpoint(watchpoint);
94
95	if (!watchpoint->IsInstalled())
96		return;
97
98	status_t error = fDebuggerInterface->UninstallWatchpoint(
99		watchpoint->Address());
100
101	if (error == B_OK) {
102		watchpoint->SetInstalled(false);
103		fTeam->NotifyWatchpointChanged(watchpoint);
104	}
105}
106