1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2013-2016, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
5 */
6#ifndef TEAM_H
7#define TEAM_H
8
9#include <map>
10
11#include <Locker.h>
12#include <StringList.h>
13
14#include <ObjectList.h>
15
16#include "Image.h"
17#include "ImageInfo.h"
18#include "TargetAddressRange.h"
19#include "Thread.h"
20#include "ThreadInfo.h"
21#include "UserBreakpoint.h"
22#include "Watchpoint.h"
23
24
25// team event types
26enum {
27	TEAM_EVENT_TEAM_RENAMED,
28
29	TEAM_EVENT_THREAD_ADDED,
30	TEAM_EVENT_THREAD_REMOVED,
31	TEAM_EVENT_IMAGE_ADDED,
32	TEAM_EVENT_IMAGE_REMOVED,
33
34	TEAM_EVENT_THREAD_STATE_CHANGED,
35	TEAM_EVENT_THREAD_CPU_STATE_CHANGED,
36	TEAM_EVENT_THREAD_STACK_TRACE_CHANGED,
37
38	TEAM_EVENT_IMAGE_DEBUG_INFO_CHANGED,
39
40	TEAM_EVENT_IMAGE_LOAD_SETTINGS_CHANGED,
41	TEAM_EVENT_IMAGE_LOAD_NAME_ADDED,
42	TEAM_EVENT_IMAGE_LOAD_NAME_REMOVED,
43
44	TEAM_EVENT_DEFAULT_SIGNAL_DISPOSITION_CHANGED,
45	TEAM_EVENT_CUSTOM_SIGNAL_DISPOSITION_CHANGED,
46	TEAM_EVENT_CUSTOM_SIGNAL_DISPOSITION_REMOVED,
47
48	TEAM_EVENT_CONSOLE_OUTPUT_RECEIVED,
49
50	TEAM_EVENT_BREAKPOINT_ADDED,
51	TEAM_EVENT_BREAKPOINT_REMOVED,
52	TEAM_EVENT_USER_BREAKPOINT_CHANGED,
53
54	TEAM_EVENT_WATCHPOINT_ADDED,
55	TEAM_EVENT_WATCHPOINT_REMOVED,
56	TEAM_EVENT_WATCHPOINT_CHANGED,
57
58	TEAM_EVENT_DEBUG_REPORT_CHANGED,
59
60	TEAM_EVENT_CORE_FILE_CHANGED,
61
62	TEAM_EVENT_MEMORY_CHANGED
63};
64
65
66class Architecture;
67class Breakpoint;
68class BStringList;
69class Function;
70class FunctionID;
71class FunctionInstance;
72class LocatableFile;
73class SourceCode;
74class SourceLocation;
75class Statement;
76class TeamDebugInfo;
77class TeamMemory;
78class TeamTypeInformation;
79class UserBreakpoint;
80class Value;
81
82
83typedef std::map<int32, int32> SignalDispositionMappings;
84
85
86class Team {
87public:
88			class Event;
89			class BreakpointEvent;
90			class ConsoleOutputEvent;
91			class DebugReportEvent;
92			class MemoryChangedEvent;
93			class ImageEvent;
94			class ImageLoadEvent;
95			class ImageLoadNameEvent;
96			class DefaultSignalDispositionEvent;
97			class CustomSignalDispositionEvent;
98			class ThreadEvent;
99			class UserBreakpointEvent;
100			class WatchpointEvent;
101			class CoreFileChangedEvent;
102			class Listener;
103
104public:
105								Team(team_id teamID, TeamMemory* teamMemory,
106									Architecture* architecture,
107									TeamDebugInfo* debugInfo,
108									TeamTypeInformation* typeInformation);
109								~Team();
110
111			status_t			Init();
112
113			bool				Lock()		{ return fLock.Lock(); }
114			void				Unlock()	{ fLock.Unlock(); }
115
116			team_id				ID() const			{ return fID; }
117			TeamMemory*			GetTeamMemory() const
118									{ return fTeamMemory; }
119			Architecture*		GetArchitecture() const
120									{ return fArchitecture; }
121			TeamDebugInfo*		DebugInfo() const	{ return fDebugInfo; }
122			TeamTypeInformation*
123								GetTeamTypeInformation() const
124									{ return fTypeInformation; }
125
126			const char*			Name() const	{ return fName.String(); }
127			void				SetName(const BString& name);
128
129			void				AddThread(::Thread* thread);
130			status_t			AddThread(const ThreadInfo& threadInfo,
131									::Thread** _thread = NULL);
132			void				RemoveThread(::Thread* thread);
133			bool				RemoveThread(thread_id threadID);
134			::Thread*			ThreadByID(thread_id threadID) const;
135			const ThreadList&	Threads() const;
136
137			status_t			AddImage(const ImageInfo& imageInfo,
138									LocatableFile* imageFile,
139									Image** _image = NULL);
140			void				RemoveImage(Image* image);
141			bool				RemoveImage(image_id imageID);
142			Image*				ImageByID(image_id imageID) const;
143			Image*				ImageByAddress(target_addr_t address) const;
144			const ImageList&	Images() const;
145			void				ClearImages();
146
147			bool				AddStopImageName(const BString& name);
148			void				RemoveStopImageName(const BString& name);
149			const BStringList&	StopImageNames() const;
150
151			void				SetStopOnImageLoad(bool enabled,
152									bool useImageNameList);
153			bool				StopOnImageLoad() const
154									{ return fStopOnImageLoad; }
155			bool				StopImageNameListEnabled() const
156									{ return fStopImageNameListEnabled; }
157
158			void				SetDefaultSignalDisposition(int32 disposition);
159			int32				DefaultSignalDisposition() const
160									{ return fDefaultSignalDisposition; }
161			bool				SetCustomSignalDisposition(int32 signal,
162									int32 disposition);
163			void				RemoveCustomSignalDisposition(int32 signal);
164			int32				SignalDispositionFor(int32 signal) const;
165									// if no custom disposition is found,
166									// returns default
167			const SignalDispositionMappings&
168								GetSignalDispositionMappings() const;
169
170			void				ClearSignalDispositionMappings();
171
172			bool				AddBreakpoint(Breakpoint* breakpoint);
173									// takes over reference (also on error)
174			void				RemoveBreakpoint(Breakpoint* breakpoint);
175									// releases its own reference
176			int32				CountBreakpoints() const;
177			Breakpoint*			BreakpointAt(int32 index) const;
178			Breakpoint*			BreakpointAtAddress(
179									target_addr_t address) const;
180			void				GetBreakpointsInAddressRange(
181									TargetAddressRange range,
182									BObjectList<UserBreakpoint>& breakpoints)
183										const;
184			void				GetBreakpointsForSourceCode(
185									SourceCode* sourceCode,
186									BObjectList<UserBreakpoint>& breakpoints)
187										const;
188
189			void				AddUserBreakpoint(
190									UserBreakpoint* userBreakpoint);
191			void				RemoveUserBreakpoint(
192									UserBreakpoint* userBreakpoint);
193			const UserBreakpointList& UserBreakpoints() const
194									{ return fUserBreakpoints; }
195
196			bool				AddWatchpoint(Watchpoint* watchpoint);
197									// takes over reference (also on error)
198			void				RemoveWatchpoint(Watchpoint* watchpoint);
199									// releases its own reference
200			int32				CountWatchpoints() const;
201			Watchpoint*			WatchpointAt(int32 index) const;
202			Watchpoint*			WatchpointAtAddress(
203									target_addr_t address) const;
204			void				GetWatchpointsInAddressRange(
205									TargetAddressRange range,
206									BObjectList<Watchpoint>& watchpoints)
207										const;
208			const WatchpointList& Watchpoints() const
209									{ return fWatchpoints; }
210
211			status_t			GetStatementAtAddress(target_addr_t address,
212									FunctionInstance*& _function,
213									Statement*& _statement);
214									// returns a reference to the statement,
215									// not to the functions instance, though,
216									// caller must lock
217			status_t			GetStatementAtSourceLocation(
218									SourceCode* sourceCode,
219									const SourceLocation& location,
220									Statement*& _statement);
221									// returns a reference to the statement
222									// (any matching statement!),
223									// caller must lock,
224
225			Function*			FunctionByID(FunctionID* functionID) const;
226
227			void				AddListener(Listener* listener);
228			void				RemoveListener(Listener* listener);
229
230			// service methods for Thread
231			void				NotifyThreadStateChanged(::Thread* thread);
232			void				NotifyThreadCpuStateChanged(::Thread* thread);
233			void				NotifyThreadStackTraceChanged(
234									::Thread* thread);
235
236			// service methods for Image
237			void				NotifyImageDebugInfoChanged(Image* image);
238
239			// service methods for Image load settings
240			void				NotifyStopOnImageLoadChanged(bool enabled,
241									bool useImageNameList);
242			void				NotifyStopImageNameAdded(const BString& name);
243			void				NotifyStopImageNameRemoved(
244									const BString& name);
245
246			// service methods for Signal Disposition settings
247			void				NotifyDefaultSignalDispositionChanged(
248									int32 newDisposition);
249			void				NotifyCustomSignalDispositionChanged(
250									int32 signal, int32 disposition);
251			void				NotifyCustomSignalDispositionRemoved(
252									int32 signal);
253
254			// service methods for console output
255			void				NotifyConsoleOutputReceived(
256									int32 fd, const BString& output);
257
258			// breakpoint related service methods
259			void				NotifyUserBreakpointChanged(
260									UserBreakpoint* breakpoint);
261
262			// watchpoint related service methods
263			void				NotifyWatchpointChanged(
264									Watchpoint* watchpoint);
265
266			// debug report related service methods
267			void				NotifyDebugReportChanged(
268									const char* reportPath, status_t result);
269
270			// core file related service methods
271			void				NotifyCoreFileChanged(
272									const char* targetPath);
273
274			// memory write related service methods
275			void				NotifyMemoryChanged(target_addr_t address,
276									target_size_t size);
277
278private:
279			struct BreakpointByAddressPredicate;
280			struct WatchpointByAddressPredicate;
281
282			typedef BObjectList<Breakpoint> BreakpointList;
283			typedef DoublyLinkedList<Listener> ListenerList;
284
285private:
286			void				_NotifyTeamRenamed();
287			void				_NotifyThreadAdded(::Thread* thread);
288			void				_NotifyThreadRemoved(::Thread* thread);
289			void				_NotifyImageAdded(Image* image);
290			void				_NotifyImageRemoved(Image* image);
291
292private:
293			BLocker				fLock;
294			team_id				fID;
295			TeamMemory*			fTeamMemory;
296			TeamTypeInformation*
297								fTypeInformation;
298			Architecture*		fArchitecture;
299			TeamDebugInfo*		fDebugInfo;
300			BString				fName;
301			ThreadList			fThreads;
302			ImageList			fImages;
303			bool				fStopOnImageLoad;
304			bool				fStopImageNameListEnabled;
305			BStringList			fStopImageNames;
306			int32				fDefaultSignalDisposition;
307			SignalDispositionMappings
308								fCustomSignalDispositions;
309			BreakpointList		fBreakpoints;
310			WatchpointList		fWatchpoints;
311			UserBreakpointList	fUserBreakpoints;
312			ListenerList		fListeners;
313};
314
315
316class Team::Event {
317public:
318								Event(uint32 type, Team* team);
319
320			uint32				EventType() const	{ return fEventType; }
321			Team*				GetTeam() const		{ return fTeam; }
322
323protected:
324			uint32				fEventType;
325			Team*				fTeam;
326};
327
328
329class Team::ThreadEvent : public Event {
330public:
331								ThreadEvent(uint32 type, ::Thread* thread);
332
333			::Thread*			GetThread() const	{ return fThread; }
334
335protected:
336			::Thread*			fThread;
337};
338
339
340class Team::ImageEvent : public Event {
341public:
342								ImageEvent(uint32 type, Image* image);
343
344			Image*				GetImage() const	{ return fImage; }
345
346protected:
347			Image*				fImage;
348};
349
350
351class Team::ImageLoadEvent : public Event {
352public:
353								ImageLoadEvent(uint32 type, Team* team,
354									bool stopOnImageLoad,
355									bool stopImageNameListEnabled);
356
357			bool				StopOnImageLoad() const
358									{ return fStopOnImageLoad; }
359			bool				StopImageNameListEnabled() const
360									{ return fStopImageNameListEnabled; }
361
362private:
363			bool				fStopOnImageLoad;
364			bool				fStopImageNameListEnabled;
365};
366
367
368class Team::ImageLoadNameEvent : public Event {
369public:
370								ImageLoadNameEvent(uint32 type, Team* team,
371									const BString& name);
372
373			const BString&		ImageName() const { return fImageName; }
374
375private:
376			BString				fImageName;
377};
378
379
380class Team::DefaultSignalDispositionEvent : public Event {
381public:
382								DefaultSignalDispositionEvent(uint32 type,
383									Team* team, int32 disposition);
384
385			int32				DefaultDisposition() const
386									{ return fDefaultDisposition; }
387
388private:
389			int32				fDefaultDisposition;
390};
391
392
393class Team::CustomSignalDispositionEvent : public Event {
394public:
395								CustomSignalDispositionEvent(uint32 type,
396									Team* team, int32 signal,
397									int32 disposition);
398
399			int32				Signal() const { return fSignal; }
400			int32				Disposition() const { return fDisposition; }
401
402private:
403			int32				fSignal;
404			int32				fDisposition;
405};
406
407
408class Team::BreakpointEvent : public Event {
409public:
410								BreakpointEvent(uint32 type, Team* team,
411									Breakpoint* breakpoint);
412
413			Breakpoint*			GetBreakpoint() const	{ return fBreakpoint; }
414
415protected:
416			Breakpoint*			fBreakpoint;
417};
418
419
420class Team::ConsoleOutputEvent : public Event {
421public:
422								ConsoleOutputEvent(uint32 type, Team* team,
423									int32 fd, const BString& output);
424
425			int32				Descriptor() const	{ return fDescriptor; }
426			const BString&		Output() const		{ return fOutput; }
427
428protected:
429			int32				fDescriptor;
430			BString				fOutput;
431};
432
433
434class Team::DebugReportEvent : public Event {
435public:
436								DebugReportEvent(uint32 type, Team* team,
437									const char* reportPath,
438									status_t finalStatus);
439
440			const char*			GetReportPath() const	{ return fReportPath; }
441			status_t			GetFinalStatus() const	{ return fFinalStatus; }
442protected:
443			const char*			fReportPath;
444			status_t			fFinalStatus;
445};
446
447
448class Team::CoreFileChangedEvent : public Event {
449public:
450								CoreFileChangedEvent(uint32 type, Team* team,
451									const char* targetPath);
452			const char*			GetTargetPath() const	{ return fTargetPath; }
453protected:
454			const char*			fTargetPath;
455};
456
457
458class Team::MemoryChangedEvent : public Event {
459public:
460								MemoryChangedEvent(uint32 type, Team* team,
461									target_addr_t address, target_size_t size);
462
463			target_addr_t		GetTargetAddress() const
464									{ return fTargetAddress; }
465
466			target_size_t		GetSize() const	{ return fSize; }
467protected:
468			target_addr_t		fTargetAddress;
469			target_size_t		fSize;
470};
471
472
473class Team::WatchpointEvent : public Event {
474public:
475								WatchpointEvent(uint32 type, Team* team,
476									Watchpoint* watchpoint);
477
478			Watchpoint*			GetWatchpoint() const	{ return fWatchpoint; }
479
480protected:
481			Watchpoint*			fWatchpoint;
482};
483
484
485class Team::UserBreakpointEvent : public Event {
486public:
487								UserBreakpointEvent(uint32 type, Team* team,
488									UserBreakpoint* breakpoint);
489
490			UserBreakpoint*		GetBreakpoint() const	{ return fBreakpoint; }
491
492protected:
493			UserBreakpoint*		fBreakpoint;
494};
495
496
497class Team::Listener : public DoublyLinkedListLinkImpl<Team::Listener> {
498public:
499	virtual						~Listener();
500
501	virtual	void				TeamRenamed(
502									const Team::Event& event);
503
504	virtual	void				ThreadAdded(const Team::ThreadEvent& event);
505	virtual	void				ThreadRemoved(const Team::ThreadEvent& event);
506
507	virtual	void				ImageAdded(const Team::ImageEvent& event);
508	virtual	void				ImageRemoved(const Team::ImageEvent& event);
509
510	virtual	void				ThreadStateChanged(
511									const Team::ThreadEvent& event);
512	virtual	void				ThreadCpuStateChanged(
513									const Team::ThreadEvent& event);
514	virtual	void				ThreadStackTraceChanged(
515									const Team::ThreadEvent& event);
516
517	virtual	void				ImageDebugInfoChanged(
518									const Team::ImageEvent& event);
519
520	virtual	void				StopOnImageLoadSettingsChanged(
521									const Team::ImageLoadEvent& event);
522	virtual	void				StopOnImageLoadNameAdded(
523									const Team::ImageLoadNameEvent& event);
524	virtual	void				StopOnImageLoadNameRemoved(
525									const Team::ImageLoadNameEvent& event);
526
527	virtual	void				DefaultSignalDispositionChanged(
528									const Team::DefaultSignalDispositionEvent&
529										event);
530	virtual	void				CustomSignalDispositionChanged(
531									const Team::CustomSignalDispositionEvent&
532										event);
533	virtual	void				CustomSignalDispositionRemoved(
534									const Team::CustomSignalDispositionEvent&
535										event);
536
537	virtual	void				ConsoleOutputReceived(
538									const Team::ConsoleOutputEvent& event);
539
540	virtual	void				BreakpointAdded(
541									const Team::BreakpointEvent& event);
542	virtual	void				BreakpointRemoved(
543									const Team::BreakpointEvent& event);
544	virtual	void				UserBreakpointChanged(
545									const Team::UserBreakpointEvent& event);
546
547	virtual	void				WatchpointAdded(
548									const Team::WatchpointEvent& event);
549	virtual	void				WatchpointRemoved(
550									const Team::WatchpointEvent& event);
551	virtual	void				WatchpointChanged(
552									const Team::WatchpointEvent& event);
553
554	virtual void				DebugReportChanged(
555									const Team::DebugReportEvent& event);
556
557	virtual	void				CoreFileChanged(
558									const Team::CoreFileChangedEvent& event);
559
560	virtual	void				MemoryChanged(
561									const Team::MemoryChangedEvent& event);
562};
563
564
565#endif	// TEAM_H
566