1/*
2 * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2013-2015, Rene Gollent, rene@gollent.com.
4 * Distributed under the terms of the MIT License.
5 */
6
7
8#include "Team.h"
9
10#include <new>
11
12#include <AutoLocker.h>
13
14#include "Breakpoint.h"
15#include "DisassembledCode.h"
16#include "FileSourceCode.h"
17#include "Function.h"
18#include "ImageDebugInfo.h"
19#include "SignalDispositionTypes.h"
20#include "SourceCode.h"
21#include "SpecificImageDebugInfo.h"
22#include "Statement.h"
23#include "TeamDebugInfo.h"
24#include "Tracing.h"
25#include "Value.h"
26#include "Watchpoint.h"
27
28
29// #pragma mark - BreakpointByAddressPredicate
30
31
32struct Team::BreakpointByAddressPredicate
33	: UnaryPredicate<Breakpoint> {
34	BreakpointByAddressPredicate(target_addr_t address)
35		:
36		fAddress(address)
37	{
38	}
39
40	virtual int operator()(const Breakpoint* breakpoint) const
41	{
42		return -Breakpoint::CompareAddressBreakpoint(&fAddress, breakpoint);
43	}
44
45private:
46	target_addr_t	fAddress;
47};
48
49
50// #pragma mark - WatchpointByAddressPredicate
51
52
53struct Team::WatchpointByAddressPredicate
54	: UnaryPredicate<Watchpoint> {
55	WatchpointByAddressPredicate(target_addr_t address)
56		:
57		fAddress(address)
58	{
59	}
60
61	virtual int operator()(const Watchpoint* watchpoint) const
62	{
63		return -Watchpoint::CompareAddressWatchpoint(&fAddress, watchpoint);
64	}
65
66private:
67	target_addr_t	fAddress;
68};
69
70
71// #pragma mark - Team
72
73
74Team::Team(team_id teamID, TeamMemory* teamMemory, Architecture* architecture,
75	TeamDebugInfo* debugInfo, TeamTypeInformation* typeInformation)
76	:
77	fLock("team lock"),
78	fID(teamID),
79	fTeamMemory(teamMemory),
80	fTypeInformation(typeInformation),
81	fArchitecture(architecture),
82	fDebugInfo(debugInfo),
83	fStopOnImageLoad(false),
84	fStopImageNameListEnabled(false),
85	fDefaultSignalDisposition(SIGNAL_DISPOSITION_IGNORE)
86{
87	fDebugInfo->AcquireReference();
88}
89
90
91Team::~Team()
92{
93	while (UserBreakpoint* userBreakpoint = fUserBreakpoints.RemoveHead())
94		userBreakpoint->ReleaseReference();
95
96	for (int32 i = 0; Breakpoint* breakpoint = fBreakpoints.ItemAt(i); i++)
97		breakpoint->ReleaseReference();
98
99	for (int32 i = 0; Watchpoint* watchpoint = fWatchpoints.ItemAt(i); i++)
100		watchpoint->ReleaseReference();
101
102	while (Image* image = fImages.RemoveHead())
103		image->ReleaseReference();
104
105	while (Thread* thread = fThreads.RemoveHead())
106		thread->ReleaseReference();
107
108	fDebugInfo->ReleaseReference();
109}
110
111
112status_t
113Team::Init()
114{
115	return fLock.InitCheck();
116}
117
118
119void
120Team::SetName(const BString& name)
121{
122	fName = name;
123	_NotifyTeamRenamed();
124}
125
126
127void
128Team::AddThread(Thread* thread)
129{
130	fThreads.Add(thread);
131	_NotifyThreadAdded(thread);
132}
133
134
135
136status_t
137Team::AddThread(const ThreadInfo& threadInfo, Thread** _thread)
138{
139	Thread* thread = new(std::nothrow) Thread(this, threadInfo.ThreadID());
140	if (thread == NULL)
141		return B_NO_MEMORY;
142
143	status_t error = thread->Init();
144	if (error != B_OK) {
145		delete thread;
146		return error;
147	}
148
149	thread->SetName(threadInfo.Name());
150	AddThread(thread);
151
152	if (_thread != NULL)
153		*_thread = thread;
154
155	return B_OK;
156}
157
158
159void
160Team::RemoveThread(Thread* thread)
161{
162	fThreads.Remove(thread);
163	_NotifyThreadRemoved(thread);
164}
165
166
167bool
168Team::RemoveThread(thread_id threadID)
169{
170	Thread* thread = ThreadByID(threadID);
171	if (thread == NULL)
172		return false;
173
174	RemoveThread(thread);
175	thread->ReleaseReference();
176	return true;
177}
178
179
180Thread*
181Team::ThreadByID(thread_id threadID) const
182{
183	for (ThreadList::ConstIterator it = fThreads.GetIterator();
184			Thread* thread = it.Next();) {
185		if (thread->ID() == threadID)
186			return thread;
187	}
188
189	return NULL;
190}
191
192
193const ThreadList&
194Team::Threads() const
195{
196	return fThreads;
197}
198
199
200status_t
201Team::AddImage(const ImageInfo& imageInfo, LocatableFile* imageFile,
202	Image** _image)
203{
204	Image* image = new(std::nothrow) Image(this, imageInfo, imageFile);
205	if (image == NULL)
206		return B_NO_MEMORY;
207
208	status_t error = image->Init();
209	if (error != B_OK) {
210		delete image;
211		return error;
212	}
213
214	if (image->Type() == B_APP_IMAGE)
215		SetName(image->Name());
216
217	fImages.Add(image);
218	_NotifyImageAdded(image);
219
220	if (_image != NULL)
221		*_image = image;
222
223	return B_OK;
224}
225
226
227void
228Team::RemoveImage(Image* image)
229{
230	fImages.Remove(image);
231	_NotifyImageRemoved(image);
232}
233
234
235bool
236Team::RemoveImage(image_id imageID)
237{
238	Image* image = ImageByID(imageID);
239	if (image == NULL)
240		return false;
241
242	RemoveImage(image);
243	image->ReleaseReference();
244	return true;
245}
246
247
248Image*
249Team::ImageByID(image_id imageID) const
250{
251	for (ImageList::ConstIterator it = fImages.GetIterator();
252			Image* image = it.Next();) {
253		if (image->ID() == imageID)
254			return image;
255	}
256
257	return NULL;
258}
259
260
261Image*
262Team::ImageByAddress(target_addr_t address) const
263{
264	for (ImageList::ConstIterator it = fImages.GetIterator();
265			Image* image = it.Next();) {
266		if (image->ContainsAddress(address))
267			return image;
268	}
269
270	return NULL;
271}
272
273
274const ImageList&
275Team::Images() const
276{
277	return fImages;
278}
279
280
281void
282Team::ClearImages()
283{
284	while (!fImages.IsEmpty())
285		RemoveImage(fImages.First());
286}
287
288
289bool
290Team::AddStopImageName(const BString& name)
291{
292	if (!fStopImageNames.Add(name))
293		return false;
294
295	fStopImageNames.Sort();
296
297	NotifyStopImageNameAdded(name);
298	return true;
299}
300
301
302void
303Team::RemoveStopImageName(const BString& name)
304{
305	fStopImageNames.Remove(name);
306	NotifyStopImageNameRemoved(name);
307}
308
309
310void
311Team::SetStopOnImageLoad(bool enabled, bool useImageNameList)
312{
313	fStopOnImageLoad = enabled;
314	fStopImageNameListEnabled = useImageNameList;
315	NotifyStopOnImageLoadChanged(enabled, useImageNameList);
316}
317
318
319const BStringList&
320Team::StopImageNames() const
321{
322	return fStopImageNames;
323}
324
325
326void
327Team::SetDefaultSignalDisposition(int32 disposition)
328{
329	if (disposition != fDefaultSignalDisposition) {
330		fDefaultSignalDisposition = disposition;
331		NotifyDefaultSignalDispositionChanged(disposition);
332	}
333}
334
335
336bool
337Team::SetCustomSignalDisposition(int32 signal, int32 disposition)
338{
339	SignalDispositionMappings::iterator it = fCustomSignalDispositions.find(
340		signal);
341	if (it != fCustomSignalDispositions.end() && it->second == disposition)
342		return true;
343
344	try {
345		fCustomSignalDispositions[signal] = disposition;
346	} catch (...) {
347		return false;
348	}
349
350	NotifyCustomSignalDispositionChanged(signal, disposition);
351
352	return true;
353}
354
355
356void
357Team::RemoveCustomSignalDisposition(int32 signal)
358{
359	SignalDispositionMappings::iterator it = fCustomSignalDispositions.find(
360		signal);
361	if (it == fCustomSignalDispositions.end())
362		return;
363
364	fCustomSignalDispositions.erase(it);
365
366	NotifyCustomSignalDispositionRemoved(signal);
367}
368
369
370int32
371Team::SignalDispositionFor(int32 signal) const
372{
373	SignalDispositionMappings::const_iterator it
374		= fCustomSignalDispositions.find(signal);
375	if (it != fCustomSignalDispositions.end())
376		return it->second;
377
378	return fDefaultSignalDisposition;
379}
380
381
382const SignalDispositionMappings&
383Team::GetSignalDispositionMappings() const
384{
385	return fCustomSignalDispositions;
386}
387
388
389void
390Team::ClearSignalDispositionMappings()
391{
392	fCustomSignalDispositions.clear();
393}
394
395
396bool
397Team::AddBreakpoint(Breakpoint* breakpoint)
398{
399	if (fBreakpoints.BinaryInsert(breakpoint, &Breakpoint::CompareBreakpoints))
400		return true;
401
402	breakpoint->ReleaseReference();
403	return false;
404}
405
406
407void
408Team::RemoveBreakpoint(Breakpoint* breakpoint)
409{
410	int32 index = fBreakpoints.BinarySearchIndex(*breakpoint,
411		&Breakpoint::CompareBreakpoints);
412	if (index < 0)
413		return;
414
415	fBreakpoints.RemoveItemAt(index);
416	breakpoint->ReleaseReference();
417}
418
419
420int32
421Team::CountBreakpoints() const
422{
423	return fBreakpoints.CountItems();
424}
425
426
427Breakpoint*
428Team::BreakpointAt(int32 index) const
429{
430	return fBreakpoints.ItemAt(index);
431}
432
433
434Breakpoint*
435Team::BreakpointAtAddress(target_addr_t address) const
436{
437	return fBreakpoints.BinarySearchByKey(address,
438		&Breakpoint::CompareAddressBreakpoint);
439}
440
441
442void
443Team::GetBreakpointsInAddressRange(TargetAddressRange range,
444	BObjectList<UserBreakpoint>& breakpoints) const
445{
446	int32 index = fBreakpoints.FindBinaryInsertionIndex(
447		BreakpointByAddressPredicate(range.Start()));
448	for (; Breakpoint* breakpoint = fBreakpoints.ItemAt(index); index++) {
449		if (breakpoint->Address() > range.End())
450			break;
451
452		for (UserBreakpointInstanceList::ConstIterator it
453				= breakpoint->UserBreakpoints().GetIterator();
454			UserBreakpointInstance* instance = it.Next();) {
455			breakpoints.AddItem(instance->GetUserBreakpoint());
456		}
457	}
458
459	// TODO: Avoid duplicates!
460}
461
462
463void
464Team::GetBreakpointsForSourceCode(SourceCode* sourceCode,
465	BObjectList<UserBreakpoint>& breakpoints) const
466{
467	if (DisassembledCode* disassembledCode
468			= dynamic_cast<DisassembledCode*>(sourceCode)) {
469		GetBreakpointsInAddressRange(disassembledCode->StatementAddressRange(),
470			breakpoints);
471		return;
472	}
473
474	LocatableFile* sourceFile = sourceCode->GetSourceFile();
475	if (sourceFile == NULL)
476		return;
477
478	// TODO: This can probably be optimized. Maybe by registering the user
479	// breakpoints with the team and sorting them by source code.
480	for (int32 i = 0; Breakpoint* breakpoint = fBreakpoints.ItemAt(i); i++) {
481		UserBreakpointInstance* userBreakpointInstance
482			= breakpoint->FirstUserBreakpoint();
483		if (userBreakpointInstance == NULL)
484			continue;
485
486		UserBreakpoint* userBreakpoint
487			= userBreakpointInstance->GetUserBreakpoint();
488		if (userBreakpoint->Location().SourceFile() == sourceFile)
489			breakpoints.AddItem(userBreakpoint);
490	}
491}
492
493
494void
495Team::AddUserBreakpoint(UserBreakpoint* userBreakpoint)
496{
497	fUserBreakpoints.Add(userBreakpoint);
498	userBreakpoint->AcquireReference();
499}
500
501
502void
503Team::RemoveUserBreakpoint(UserBreakpoint* userBreakpoint)
504{
505	fUserBreakpoints.Remove(userBreakpoint);
506	userBreakpoint->ReleaseReference();
507}
508
509
510bool
511Team::AddWatchpoint(Watchpoint* watchpoint)
512{
513	if (fWatchpoints.BinaryInsert(watchpoint, &Watchpoint::CompareWatchpoints))
514		return true;
515
516	watchpoint->ReleaseReference();
517	return false;
518}
519
520
521void
522Team::RemoveWatchpoint(Watchpoint* watchpoint)
523{
524	int32 index = fWatchpoints.BinarySearchIndex(*watchpoint,
525		&Watchpoint::CompareWatchpoints);
526	if (index < 0)
527		return;
528
529	fWatchpoints.RemoveItemAt(index);
530	watchpoint->ReleaseReference();
531}
532
533
534int32
535Team::CountWatchpoints() const
536{
537	return fWatchpoints.CountItems();
538}
539
540
541Watchpoint*
542Team::WatchpointAt(int32 index) const
543{
544	return fWatchpoints.ItemAt(index);
545}
546
547
548Watchpoint*
549Team::WatchpointAtAddress(target_addr_t address) const
550{
551	return fWatchpoints.BinarySearchByKey(address,
552		&Watchpoint::CompareAddressWatchpoint);
553}
554
555
556void
557Team::GetWatchpointsInAddressRange(TargetAddressRange range,
558	BObjectList<Watchpoint>& watchpoints) const
559{
560	int32 index = fWatchpoints.FindBinaryInsertionIndex(
561		WatchpointByAddressPredicate(range.Start()));
562	for (; Watchpoint* watchpoint = fWatchpoints.ItemAt(index); index++) {
563		if (watchpoint->Address() > range.End())
564			break;
565
566		watchpoints.AddItem(watchpoint);
567	}
568}
569
570
571status_t
572Team::GetStatementAtAddress(target_addr_t address, FunctionInstance*& _function,
573	Statement*& _statement)
574{
575	TRACE_CODE("Team::GetStatementAtAddress(%#" B_PRIx64 ")\n", address);
576
577	// get the image at the address
578	Image* image = ImageByAddress(address);
579	if (image == NULL) {
580		TRACE_CODE("  -> no image\n");
581		return B_ENTRY_NOT_FOUND;
582	}
583
584	ImageDebugInfo* imageDebugInfo = image->GetImageDebugInfo();
585	if (imageDebugInfo == NULL) {
586		TRACE_CODE("  -> no image debug info\n");
587		return B_ENTRY_NOT_FOUND;
588	}
589
590	// get the function
591	FunctionInstance* functionInstance
592		= imageDebugInfo->FunctionAtAddress(address);
593	if (functionInstance == NULL) {
594		TRACE_CODE("  -> no function instance\n");
595		return B_ENTRY_NOT_FOUND;
596	}
597
598	// If the function instance has disassembled code attached, we can get the
599	// statement directly.
600	if (DisassembledCode* code = functionInstance->GetSourceCode()) {
601		Statement* statement = code->StatementAtAddress(address);
602		if (statement == NULL)
603			return B_ENTRY_NOT_FOUND;
604
605		statement->AcquireReference();
606		_statement = statement;
607		_function = functionInstance;
608		return B_OK;
609	}
610
611	// get the statement from the image debug info
612	FunctionDebugInfo* functionDebugInfo
613		= functionInstance->GetFunctionDebugInfo();
614	status_t error = functionDebugInfo->GetSpecificImageDebugInfo()
615		->GetStatement(functionDebugInfo, address, _statement);
616	if (error != B_OK) {
617		TRACE_CODE("  -> no statement from the specific image debug info\n");
618		return error;
619	}
620
621	_function = functionInstance;
622	return B_OK;
623}
624
625
626status_t
627Team::GetStatementAtSourceLocation(SourceCode* sourceCode,
628	const SourceLocation& location, Statement*& _statement)
629{
630	TRACE_CODE("Team::GetStatementAtSourceLocation(%p, (%" B_PRId32 ", %"
631		B_PRId32 "))\n", sourceCode, location.Line(), location.Column());
632
633	// If we're lucky the source code can provide us with a statement.
634	if (DisassembledCode* code = dynamic_cast<DisassembledCode*>(sourceCode)) {
635		Statement* statement = code->StatementAtLocation(location);
636		if (statement == NULL)
637			return B_ENTRY_NOT_FOUND;
638
639		statement->AcquireReference();
640		_statement = statement;
641		return B_OK;
642	}
643
644	// Go the long and stony way over the source file and the team debug info.
645	// get the source file for the source code
646	LocatableFile* sourceFile = sourceCode->GetSourceFile();
647	if (sourceFile == NULL)
648		return B_ENTRY_NOT_FOUND;
649
650	// get the function at the source location
651	Function* function = fDebugInfo->FunctionAtSourceLocation(sourceFile,
652		location);
653	if (function == NULL)
654		return B_ENTRY_NOT_FOUND;
655
656	// Get some function instance and ask its image debug info to provide us
657	// with a statement.
658	FunctionInstance* functionInstance = function->FirstInstance();
659	if (functionInstance == NULL)
660		return B_ENTRY_NOT_FOUND;
661
662	FunctionDebugInfo* functionDebugInfo
663		= functionInstance->GetFunctionDebugInfo();
664	return functionDebugInfo->GetSpecificImageDebugInfo()
665		->GetStatementAtSourceLocation(functionDebugInfo, location, _statement);
666}
667
668
669Function*
670Team::FunctionByID(FunctionID* functionID) const
671{
672	return fDebugInfo->FunctionByID(functionID);
673}
674
675
676void
677Team::AddListener(Listener* listener)
678{
679	AutoLocker<Team> locker(this);
680	fListeners.Add(listener);
681}
682
683
684void
685Team::RemoveListener(Listener* listener)
686{
687	AutoLocker<Team> locker(this);
688	fListeners.Remove(listener);
689}
690
691
692void
693Team::NotifyThreadStateChanged(Thread* thread)
694{
695	for (ListenerList::Iterator it = fListeners.GetIterator();
696			Listener* listener = it.Next();) {
697		listener->ThreadStateChanged(
698			ThreadEvent(TEAM_EVENT_THREAD_STATE_CHANGED, thread));
699	}
700}
701
702
703void
704Team::NotifyThreadCpuStateChanged(Thread* thread)
705{
706	for (ListenerList::Iterator it = fListeners.GetIterator();
707			Listener* listener = it.Next();) {
708		listener->ThreadCpuStateChanged(
709			ThreadEvent(TEAM_EVENT_THREAD_CPU_STATE_CHANGED, thread));
710	}
711}
712
713
714void
715Team::NotifyThreadStackTraceChanged(Thread* thread)
716{
717	for (ListenerList::Iterator it = fListeners.GetIterator();
718			Listener* listener = it.Next();) {
719		listener->ThreadStackTraceChanged(
720			ThreadEvent(TEAM_EVENT_THREAD_STACK_TRACE_CHANGED, thread));
721	}
722}
723
724
725void
726Team::NotifyImageDebugInfoChanged(Image* image)
727{
728	for (ListenerList::Iterator it = fListeners.GetIterator();
729			Listener* listener = it.Next();) {
730		listener->ImageDebugInfoChanged(
731			ImageEvent(TEAM_EVENT_IMAGE_DEBUG_INFO_CHANGED, image));
732	}
733}
734
735
736void
737Team::NotifyStopOnImageLoadChanged(bool enabled, bool useImageNameList)
738{
739	for (ListenerList::Iterator it = fListeners.GetIterator();
740			Listener* listener = it.Next();) {
741		listener->StopOnImageLoadSettingsChanged(
742			ImageLoadEvent(TEAM_EVENT_IMAGE_LOAD_SETTINGS_CHANGED, this,
743				enabled, useImageNameList));
744	}
745}
746
747
748void
749Team::NotifyStopImageNameAdded(const BString& name)
750{
751	for (ListenerList::Iterator it = fListeners.GetIterator();
752			Listener* listener = it.Next();) {
753		listener->StopOnImageLoadNameAdded(
754			ImageLoadNameEvent(TEAM_EVENT_IMAGE_LOAD_NAME_ADDED, this, name));
755	}
756}
757
758
759void
760Team::NotifyStopImageNameRemoved(const BString& name)
761{
762	for (ListenerList::Iterator it = fListeners.GetIterator();
763			Listener* listener = it.Next();) {
764		listener->StopOnImageLoadNameRemoved(
765			ImageLoadNameEvent(TEAM_EVENT_IMAGE_LOAD_NAME_REMOVED, this,
766				name));
767	}
768}
769
770
771void
772Team::NotifyDefaultSignalDispositionChanged(int32 disposition)
773{
774	for (ListenerList::Iterator it = fListeners.GetIterator();
775			Listener* listener = it.Next();) {
776		listener->DefaultSignalDispositionChanged(
777			DefaultSignalDispositionEvent(
778				TEAM_EVENT_DEFAULT_SIGNAL_DISPOSITION_CHANGED, this,
779				disposition));
780	}
781}
782
783
784void
785Team::NotifyCustomSignalDispositionChanged(int32 signal, int32 disposition)
786{
787	for (ListenerList::Iterator it = fListeners.GetIterator();
788			Listener* listener = it.Next();) {
789		listener->CustomSignalDispositionChanged(
790			CustomSignalDispositionEvent(
791				TEAM_EVENT_CUSTOM_SIGNAL_DISPOSITION_CHANGED, this,
792				signal, disposition));
793	}
794}
795
796
797void
798Team::NotifyCustomSignalDispositionRemoved(int32 signal)
799{
800	for (ListenerList::Iterator it = fListeners.GetIterator();
801			Listener* listener = it.Next();) {
802		listener->CustomSignalDispositionRemoved(
803			CustomSignalDispositionEvent(
804				TEAM_EVENT_CUSTOM_SIGNAL_DISPOSITION_REMOVED, this,
805				signal, SIGNAL_DISPOSITION_IGNORE));
806	}
807}
808
809
810void
811Team::NotifyConsoleOutputReceived(int32 fd, const BString& output)
812{
813	for (ListenerList::Iterator it = fListeners.GetIterator();
814			Listener* listener = it.Next();) {
815		listener->ConsoleOutputReceived(
816			ConsoleOutputEvent(TEAM_EVENT_CONSOLE_OUTPUT_RECEIVED, this,
817				fd, output));
818	}
819}
820
821
822void
823Team::NotifyUserBreakpointChanged(UserBreakpoint* breakpoint)
824{
825	for (ListenerList::Iterator it = fListeners.GetIterator();
826			Listener* listener = it.Next();) {
827		listener->UserBreakpointChanged(UserBreakpointEvent(
828			TEAM_EVENT_USER_BREAKPOINT_CHANGED, this, breakpoint));
829	}
830}
831
832
833void
834Team::NotifyWatchpointChanged(Watchpoint* watchpoint)
835{
836	for (ListenerList::Iterator it = fListeners.GetIterator();
837			Listener* listener = it.Next();) {
838		listener->WatchpointChanged(WatchpointEvent(
839			TEAM_EVENT_WATCHPOINT_CHANGED, this, watchpoint));
840	}
841}
842
843
844void
845Team::NotifyDebugReportChanged(const char* reportPath, status_t result)
846{
847	for (ListenerList::Iterator it = fListeners.GetIterator();
848			Listener* listener = it.Next();) {
849		listener->DebugReportChanged(DebugReportEvent(
850			TEAM_EVENT_DEBUG_REPORT_CHANGED, this, reportPath, result));
851	}
852}
853
854
855void
856Team::NotifyCoreFileChanged(const char* targetPath)
857{
858	for (ListenerList::Iterator it = fListeners.GetIterator();
859			Listener* listener = it.Next();) {
860		listener->CoreFileChanged(CoreFileChangedEvent(
861			TEAM_EVENT_CORE_FILE_CHANGED, this, targetPath));
862	}
863}
864
865
866void
867Team::NotifyMemoryChanged(target_addr_t address, target_size_t size)
868{
869	for (ListenerList::Iterator it = fListeners.GetIterator();
870			Listener* listener = it.Next();) {
871		listener->MemoryChanged(MemoryChangedEvent(
872			TEAM_EVENT_MEMORY_CHANGED, this, address, size));
873	}
874}
875
876
877void
878Team::_NotifyTeamRenamed()
879{
880	for (ListenerList::Iterator it = fListeners.GetIterator();
881			Listener* listener = it.Next();) {
882		listener->TeamRenamed(Event(TEAM_EVENT_TEAM_RENAMED, this));
883	}
884}
885
886
887void
888Team::_NotifyThreadAdded(Thread* thread)
889{
890	for (ListenerList::Iterator it = fListeners.GetIterator();
891			Listener* listener = it.Next();) {
892		listener->ThreadAdded(ThreadEvent(TEAM_EVENT_THREAD_ADDED, thread));
893	}
894}
895
896
897void
898Team::_NotifyThreadRemoved(Thread* thread)
899{
900	for (ListenerList::Iterator it = fListeners.GetIterator();
901			Listener* listener = it.Next();) {
902		listener->ThreadRemoved(ThreadEvent(TEAM_EVENT_THREAD_REMOVED, thread));
903	}
904}
905
906
907void
908Team::_NotifyImageAdded(Image* image)
909{
910	for (ListenerList::Iterator it = fListeners.GetIterator();
911			Listener* listener = it.Next();) {
912		listener->ImageAdded(ImageEvent(TEAM_EVENT_IMAGE_ADDED, image));
913	}
914}
915
916
917void
918Team::_NotifyImageRemoved(Image* image)
919{
920	for (ListenerList::Iterator it = fListeners.GetIterator();
921			Listener* listener = it.Next();) {
922		listener->ImageRemoved(ImageEvent(TEAM_EVENT_IMAGE_REMOVED, image));
923	}
924}
925
926
927// #pragma mark - Event
928
929
930Team::Event::Event(uint32 type, Team* team)
931	:
932	fEventType(type),
933	fTeam(team)
934{
935}
936
937
938// #pragma mark - ThreadEvent
939
940
941Team::ThreadEvent::ThreadEvent(uint32 type, Thread* thread)
942	:
943	Event(type, thread->GetTeam()),
944	fThread(thread)
945{
946}
947
948
949// #pragma mark - ImageEvent
950
951
952Team::ImageEvent::ImageEvent(uint32 type, Image* image)
953	:
954	Event(type, image->GetTeam()),
955	fImage(image)
956{
957}
958
959
960// #pragma mark - ImageLoadEvent
961
962
963Team::ImageLoadEvent::ImageLoadEvent(uint32 type, Team* team,
964	bool stopOnImageLoad, bool stopImageNameListEnabled)
965	:
966	Event(type, team),
967	fStopOnImageLoad(stopOnImageLoad),
968	fStopImageNameListEnabled(stopImageNameListEnabled)
969{
970}
971
972
973// #pragma mark - ImageLoadNameEvent
974
975
976Team::ImageLoadNameEvent::ImageLoadNameEvent(uint32 type, Team* team,
977	const BString& name)
978	:
979	Event(type, team),
980	fImageName(name)
981{
982}
983
984
985// #pragma mark - DefaultSignalDispositionEvent
986
987
988Team::DefaultSignalDispositionEvent::DefaultSignalDispositionEvent(uint32 type,
989	Team* team, int32 disposition)
990	:
991	Event(type, team),
992	fDefaultDisposition(disposition)
993{
994}
995
996
997// #pragma mark - CustomSignalDispositionEvent
998
999
1000Team::CustomSignalDispositionEvent::CustomSignalDispositionEvent(uint32 type,
1001	Team* team, int32 signal, int32 disposition)
1002	:
1003	Event(type, team),
1004	fSignal(signal),
1005	fDisposition(disposition)
1006{
1007}
1008
1009
1010// #pragma mark - BreakpointEvent
1011
1012
1013Team::BreakpointEvent::BreakpointEvent(uint32 type, Team* team,
1014	Breakpoint* breakpoint)
1015	:
1016	Event(type, team),
1017	fBreakpoint(breakpoint)
1018{
1019}
1020
1021
1022// #pragma mark - ConsoleOutputEvent
1023
1024
1025Team::ConsoleOutputEvent::ConsoleOutputEvent(uint32 type, Team* team,
1026	int32 fd, const BString& output)
1027	:
1028	Event(type, team),
1029	fDescriptor(fd),
1030	fOutput(output)
1031{
1032}
1033
1034
1035// #pragma mark - DebugReportEvent
1036
1037
1038Team::DebugReportEvent::DebugReportEvent(uint32 type, Team* team,
1039	const char* reportPath, status_t finalStatus)
1040	:
1041	Event(type, team),
1042	fReportPath(reportPath),
1043	fFinalStatus(finalStatus)
1044{
1045}
1046
1047
1048// #pragma mark - CoreFileChangedEvent
1049
1050
1051Team::CoreFileChangedEvent::CoreFileChangedEvent(uint32 type, Team* team,
1052	const char* targetPath)
1053	:
1054	Event(type, team),
1055	fTargetPath(targetPath)
1056{
1057}
1058
1059
1060// #pragma mark - MemoryChangedEvent
1061
1062
1063Team::MemoryChangedEvent::MemoryChangedEvent(uint32 type, Team* team,
1064	target_addr_t address, target_size_t size)
1065	:
1066	Event(type, team),
1067	fTargetAddress(address),
1068	fSize(size)
1069{
1070}
1071
1072
1073// #pragma mark - WatchpointEvent
1074
1075
1076Team::WatchpointEvent::WatchpointEvent(uint32 type, Team* team,
1077	Watchpoint* watchpoint)
1078	:
1079	Event(type, team),
1080	fWatchpoint(watchpoint)
1081{
1082}
1083
1084
1085// #pragma mark - UserBreakpointEvent
1086
1087
1088Team::UserBreakpointEvent::UserBreakpointEvent(uint32 type, Team* team,
1089	UserBreakpoint* breakpoint)
1090	:
1091	Event(type, team),
1092	fBreakpoint(breakpoint)
1093{
1094}
1095
1096
1097// #pragma mark - Listener
1098
1099
1100Team::Listener::~Listener()
1101{
1102}
1103
1104
1105void
1106Team::Listener::TeamRenamed(const Team::Event& event)
1107{
1108}
1109
1110
1111void
1112Team::Listener::ThreadAdded(const Team::ThreadEvent& event)
1113{
1114}
1115
1116
1117void
1118Team::Listener::ThreadRemoved(const Team::ThreadEvent& event)
1119{
1120}
1121
1122
1123void
1124Team::Listener::ImageAdded(const Team::ImageEvent& event)
1125{
1126}
1127
1128
1129void
1130Team::Listener::ImageRemoved(const Team::ImageEvent& event)
1131{
1132}
1133
1134
1135void
1136Team::Listener::ThreadStateChanged(const Team::ThreadEvent& event)
1137{
1138}
1139
1140
1141void
1142Team::Listener::ThreadCpuStateChanged(const Team::ThreadEvent& event)
1143{
1144}
1145
1146
1147void
1148Team::Listener::ThreadStackTraceChanged(const Team::ThreadEvent& event)
1149{
1150}
1151
1152
1153void
1154Team::Listener::ImageDebugInfoChanged(const Team::ImageEvent& event)
1155{
1156}
1157
1158
1159void
1160Team::Listener::StopOnImageLoadSettingsChanged(
1161	const Team::ImageLoadEvent& event)
1162{
1163}
1164
1165
1166void
1167Team::Listener::StopOnImageLoadNameAdded(const Team::ImageLoadNameEvent& event)
1168{
1169}
1170
1171
1172void
1173Team::Listener::StopOnImageLoadNameRemoved(
1174	const Team::ImageLoadNameEvent& event)
1175{
1176}
1177
1178
1179void
1180Team::Listener::DefaultSignalDispositionChanged(
1181	const Team::DefaultSignalDispositionEvent& event)
1182{
1183}
1184
1185
1186void
1187Team::Listener::CustomSignalDispositionChanged(
1188	const Team::CustomSignalDispositionEvent& event)
1189{
1190}
1191
1192
1193void
1194Team::Listener::CustomSignalDispositionRemoved(
1195	const Team::CustomSignalDispositionEvent& event)
1196{
1197}
1198
1199
1200void
1201Team::Listener::ConsoleOutputReceived(const Team::ConsoleOutputEvent& event)
1202{
1203}
1204
1205
1206void
1207Team::Listener::BreakpointAdded(const Team::BreakpointEvent& event)
1208{
1209}
1210
1211
1212void
1213Team::Listener::BreakpointRemoved(const Team::BreakpointEvent& event)
1214{
1215}
1216
1217
1218void
1219Team::Listener::UserBreakpointChanged(const Team::UserBreakpointEvent& event)
1220{
1221}
1222
1223
1224void
1225Team::Listener::WatchpointAdded(const Team::WatchpointEvent& event)
1226{
1227}
1228
1229
1230void
1231Team::Listener::WatchpointRemoved(const Team::WatchpointEvent& event)
1232{
1233}
1234
1235
1236void
1237Team::Listener::WatchpointChanged(const Team::WatchpointEvent& event)
1238{
1239}
1240
1241
1242void
1243Team::Listener::DebugReportChanged(const Team::DebugReportEvent& event)
1244{
1245}
1246
1247
1248void
1249Team::Listener::CoreFileChanged(const Team::CoreFileChangedEvent& event)
1250{
1251}
1252
1253
1254void
1255Team::Listener::MemoryChanged(const Team::MemoryChangedEvent& event)
1256{
1257}
1258