os/kernelhwsrv/kernel/eka/drivers/debug/rmdebug/d_rmd_breakpoints.h
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kernel/eka/drivers/debug/rmdebug/d_rmd_breakpoints.h	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,207 @@
     1.4 +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// Refactored class containing breakpoint related code from rm_debug_kerneldriver.cpp
    1.18 +//
    1.19 +
    1.20 +
    1.21 +
    1.22 +/**
    1.23 + @file
    1.24 + @internalComponent
    1.25 + @released
    1.26 +*/
    1.27 +
    1.28 +#ifndef D_RMD_BREAKPOINTS_H
    1.29 +#define D_RMD_BREAKPOINTS_H
    1.30 +
    1.31 +#include <rm_debug_api.h>
    1.32 +#include <kernel/kern_priv.h>
    1.33 +#include "rm_debug_kerneldriver.h"
    1.34 +
    1.35 +// fwd declaration of friend classes needed due to re-factoring
    1.36 +class DRM_DebugChannel;
    1.37 +
    1.38 +class DRMDStepper;
    1.39 +
    1.40 +//
    1.41 +// Macros
    1.42 +//
    1.43 +const TUint32 KArmBreakPoint = 0xE7F123F4;
    1.44 +const TUint16 KThumbBreakPoint = 0xDE56;
    1.45 +const TUint16 KT2EEBreakPoint = 0xC100;	// From ARM ARM DDI0406A, section A9.2.1 Undefined instruction encoding for Thumb2-EE.
    1.46 +
    1.47 +#define NUMBER_OF_TEMP_BREAKPOINTS 10
    1.48 +
    1.49 +#define NUMBER_OF_MAX_BREAKPOINTS 100
    1.50 +
    1.51 +//
    1.52 +// class TBreakEntry
    1.53 +//
    1.54 +class TBreakEntry
    1.55 +{
    1.56 +public:
    1.57 +
    1.58 +	inline TBreakEntry() { Reset(); };
    1.59 +
    1.60 +	inline TBreakEntry(Debug::TBreakId aBreakId, TUint64 aId, TBool aThreadSpecific, TUint32 aAddress, Debug::TArchitectureMode aMode)
    1.61 +			: iBreakId(aBreakId),
    1.62 +			  iId(aId),
    1.63 +			  iAddress(aAddress),
    1.64 +			  iMode(aMode),
    1.65 +			  iThreadSpecific(aThreadSpecific)
    1.66 +	{
    1.67 +		 iInstruction.FillZ(4);
    1.68 +		 iPageAddress = 0;
    1.69 +		 iDisabledForStep = EFalse;
    1.70 +		 iObsoleteLibraryBreakpoint = EFalse;
    1.71 +		 iResumeOnceOutOfRange = EFalse;
    1.72 +		 iSteppingInto = EFalse;
    1.73 +		 iRangeStart = 0;
    1.74 +		 iRangeEnd = 0;
    1.75 +		 iStepTarget = EFalse;
    1.76 +		 iNumSteps = 0;
    1.77 +	};
    1.78 +	
    1.79 +	inline void Reset()
    1.80 +	{
    1.81 +		 iId = 0;
    1.82 +		 iAddress = 0;
    1.83 +		 iMode = Debug::EArmMode;
    1.84 +		 iInstruction.FillZ(4);
    1.85 +		 iPageAddress = 0;
    1.86 +		 iDisabledForStep = EFalse;
    1.87 +		 iObsoleteLibraryBreakpoint = EFalse;
    1.88 +		 iResumeOnceOutOfRange = EFalse;
    1.89 +		 iSteppingInto = EFalse;
    1.90 +		 iRangeStart = 0;
    1.91 +		 iRangeEnd = 0;
    1.92 +		 iStepTarget = EFalse;
    1.93 +		 iNumSteps = 0;
    1.94 +	};
    1.95 +
    1.96 +public:
    1.97 +	// Unique Id for this breakpoint. Assigned by D_RMD_Breakpoints::DoSetBreak(). @see D_RMD_Breakpoints::DoSetBreak
    1.98 +	TInt32		iBreakId;
    1.99 +	// Consider making the iId into a union of TProcessId, TThreadId, global etc. to make things more obvious
   1.100 +	// Object Id in which this breakpoint should operate.
   1.101 +	TUint64		iId;
   1.102 +	// Address at which this breakpoint should operate
   1.103 +	TUint32		iAddress;
   1.104 +	// CPU ISA which this breakpoint uses, e.g. EArmMode/EThumbMode.
   1.105 +	Debug::TArchitectureMode iMode;
   1.106 +	// The original instruction which was stored at iAddress.
   1.107 +	TBuf8<4>	iInstruction;
   1.108 +	TUint32		iPageAddress;   //not used: BC if we remove it
   1.109 +
   1.110 +	// Indicates whether this breakpoint has been temporarily replaced with original instruction to enable step-off this breakpoint
   1.111 +	TBool		iDisabledForStep;
   1.112 +	/* This is used when libraries and processes are removed, so that
   1.113 +	 * the driver can say 'ok' when requested to remove breakpoints
   1.114 +	 * that existed in these cases, rather than 'Not Found'.
   1.115 +	 *
   1.116 +	 * Its not logical, but its a BC break if we change it :-(
   1.117 +	 */
   1.118 +	TBool		iObsoleteLibraryBreakpoint;
   1.119 +	// Indicates whether this thread should be resumed after stepping off this breakpoint
   1.120 +	TBool		iResumeOnceOutOfRange;
   1.121 +	TBool		iSteppingInto;
   1.122 +	TUint32		iRangeStart;
   1.123 +	TUint32		iRangeEnd;
   1.124 +	TBool		iThreadSpecific;
   1.125 +	TBool		iStepTarget;
   1.126 +
   1.127 +	// Indicates how many more instruction steps should occur after hitting this breakpoint
   1.128 +	TInt		iNumSteps;
   1.129 +};
   1.130 +/**
   1.131 +@internalTechnology
   1.132 +
   1.133 +This class encapsulates all the data concerning run-mode and stop mode breakpoints
   1.134 +as understood by the run-mode and stop-mode debug system.
   1.135 +
   1.136 +Note:                                                                        
   1.137 +	The internal list of breakpoints is currently divided into two sections. The range from
   1.138 +	0...NUMBER_OF_TEMP_BREAKPOINTS is used internally by the debug driver for implementing
   1.139 +	stepping. The range from NUMBER_OF_TEMP_BREAKPOINTS to NUMBER_OF_MAX_BREAKPOINTS is used
   1.140 +	to store information about breakpoints set by the client debug agents.
   1.141 +                                                                                                                                                            
   1.142 +	In future, this should change, so that each breakpoint knows what kind of breakpoint it
   1.143 +	is (user/temp etc).
   1.144 +
   1.145 +
   1.146 +*/
   1.147 +class D_RMD_Breakpoints : public DBase
   1.148 +{
   1.149 +public:
   1.150 +	D_RMD_Breakpoints(DRM_DebugChannel* aChannel);
   1.151 +	~D_RMD_Breakpoints();
   1.152 +
   1.153 +	TInt Init();
   1.154 +
   1.155 +	// from rm_debug_driver.h
   1.156 +	TInt DoSetBreak(TInt32 &aBreakId, const TUint64 aId, const TBool aThreadSpecific, const TUint32 aAddress, const Debug::TArchitectureMode aMode );
   1.157 +	TInt DoEnableBreak(TBreakEntry &aEntry, TBool aSaveOldInstruction);
   1.158 +	TInt DoClearBreak(const TInt32 aBreakId, TBool aIgnoreTerminatedThreads=EFalse);
   1.159 +	TInt DoModifyBreak(TModifyBreakInfo* aBreakInfo);
   1.160 +	TInt DoModifyProcessBreak(TModifyProcessBreakInfo* aBreakInfo);
   1.161 +	TInt DoBreakInfo(TGetBreakInfo* aBreakInfo);
   1.162 +	void ClearAllBreakPoints();
   1.163 +	TInt DisableBreakAtAddress(TUint32 aAddress);
   1.164 +	TInt DoEnableDisabledBreak(TUint64 aThreadId);
   1.165 +
   1.166 +	void DoRemoveThreadBreaks(TUint64 aThreadId);
   1.167 +	void RemoveBreaksForProcess(TUint64 aProcessId, TUint32 aCodeAddress, TUint32 aCodeSize);
   1.168 +	void InvalidateLibraryBreakPoints(TUint32 aCodeAddress, TUint32 aCodeSize);
   1.169 +	TInt BreakPointCount() const;
   1.170 +	TBreakEntry* GetNextBreak(const TBreakEntry* aBreakEntry) const;
   1.171 +	TBool IsTemporaryBreak(const TBreakEntry& aBreakEntry) const;
   1.172 +
   1.173 +	TInt DoGetBreakList(TUint32* aBuffer, const TUint32 aBufSize, const TUint32 aElement, TUint32& aLastElement);
   1.174 +
   1.175 +private:
   1.176 +	// Locked versions of public functions
   1.177 +	TInt priv_DoSetBreak(TInt32 &aBreakId, const TUint64 aId,  const TBool aThreadSpecific, const TUint32 aAddress, const Debug::TArchitectureMode aMode );
   1.178 +	TInt priv_DoEnableBreak(TBreakEntry &aEntry, TBool aSaveOldInstruction);
   1.179 +	TInt priv_DoClearBreak(const TInt32 aBreakId, TBool aIgnoreTerminatedThreads);
   1.180 +	TInt priv_DoModifyBreak(TModifyBreakInfo* aBreakInfo);
   1.181 +	TInt priv_DoModifyProcessBreak(TModifyProcessBreakInfo* aBreakInfo);
   1.182 +	TInt priv_DoBreakInfo(TGetBreakInfo* aBreakInfo);	
   1.183 +	TInt priv_DisableBreakAtAddress(TUint32 aAddress);
   1.184 +	TInt priv_DoEnableDisabledBreak(TUint64 aThreadId);
   1.185 +	void priv_DoRemoveThreadBreaks(TUint64 aThreadId);
   1.186 +	void priv_ClearAllBreakPoints();
   1.187 +	TBool priv_IsTemporaryBreak(const TBreakEntry& aBreakEntry) const;
   1.188 +
   1.189 +	// helper functions
   1.190 +	TBool Aligned(TUint32 aAddress, Debug::TArchitectureMode aMode);
   1.191 +	TInt BreakSize(Debug::TArchitectureMode aMode);
   1.192 +	TBool BreakpointsOverlap(TBreakEntry& aFirst, TBreakEntry& aSecond);
   1.193 +	TUint32 BreakInst(Debug::TArchitectureMode aMode);
   1.194 +
   1.195 +private:
   1.196 +	RArray<TBreakEntry> iBreakPointList;
   1.197 +	TInt iNextBreakId;
   1.198 +
   1.199 +	DRM_DebugChannel* iChannel;	// temporary reference back to DRM_DebugChannel to help with refactoring
   1.200 +
   1.201 +	/* Protect access to the breakpoint list with a DSemaphore
   1.202 +	 *
   1.203 +	 * This means that stop-mode debuggers know when the list is being updated by the run-mode debug subsystem.
   1.204 +	 */
   1.205 +	DSemaphore* iLock;
   1.206 +
   1.207 +	TBool iInitialised;
   1.208 +};
   1.209 +
   1.210 +#endif