debugsrv/runmodedebug/rmdriver/src/rm_debug_kerneldriver.cpp
author hgs
Fri, 08 Oct 2010 14:56:39 +0300
changeset 56 aa2539c91954
parent 42 0ff24a8f6ca2
permissions -rw-r--r--
201041
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
42
hgs
parents:
diff changeset
     1
// Copyright (c) 2004-2010 Nokia Corporation and/or its subsidiary(-ies).
hgs
parents:
diff changeset
     2
// All rights reserved.
hgs
parents:
diff changeset
     3
// This component and the accompanying materials are made available
56
hgs
parents: 42
diff changeset
     4
// under the terms of "Eclipse Public License v1.0"
42
hgs
parents:
diff changeset
     5
// which accompanies this distribution, and is available
hgs
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
hgs
parents:
diff changeset
     7
//
hgs
parents:
diff changeset
     8
// Initial Contributors:
hgs
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
hgs
parents:
diff changeset
    10
//
hgs
parents:
diff changeset
    11
// Contributors:
hgs
parents:
diff changeset
    12
//
hgs
parents:
diff changeset
    13
// Description:
hgs
parents:
diff changeset
    14
// Device driver for kernel side debug assist
hgs
parents:
diff changeset
    15
//
hgs
parents:
diff changeset
    16
hgs
parents:
diff changeset
    17
#ifdef __WINS__
hgs
parents:
diff changeset
    18
#error - this driver cannot be built for emulation
hgs
parents:
diff changeset
    19
#endif
hgs
parents:
diff changeset
    20
hgs
parents:
diff changeset
    21
#include <e32def.h>
hgs
parents:
diff changeset
    22
#include <e32def_private.h>
hgs
parents:
diff changeset
    23
#include <e32cmn.h>
hgs
parents:
diff changeset
    24
#include <e32cmn_private.h>
hgs
parents:
diff changeset
    25
#include <e32ldr.h>
hgs
parents:
diff changeset
    26
#include <u32std.h>
hgs
parents:
diff changeset
    27
#include <kernel/kernel.h>
hgs
parents:
diff changeset
    28
#include <kernel/kern_priv.h>
hgs
parents:
diff changeset
    29
#include <nk_trace.h>
hgs
parents:
diff changeset
    30
#include <arm.h>
hgs
parents:
diff changeset
    31
#include <kernel/cache.h>
hgs
parents:
diff changeset
    32
#include <platform.h>
hgs
parents:
diff changeset
    33
#include <nkern.h>
hgs
parents:
diff changeset
    34
#include <u32hal.h>
hgs
parents:
diff changeset
    35
#include <rm_debug_api.h>
hgs
parents:
diff changeset
    36
hgs
parents:
diff changeset
    37
#include "debug_logging.h"
hgs
parents:
diff changeset
    38
#include "d_rmd_breakpoints.h"	// moved breakpoints code lives here
hgs
parents:
diff changeset
    39
#include "d_rmd_stepping.h"		// moved stepping code lives here
hgs
parents:
diff changeset
    40
#include "rm_debug_kerneldriver.h"
hgs
parents:
diff changeset
    41
#include "d_list_manager.h"
hgs
parents:
diff changeset
    42
#include "rm_debug_driver.h"
hgs
parents:
diff changeset
    43
#include "rm_debug_eventhandler.h"
hgs
parents:
diff changeset
    44
#include "d_debug_functionality.h"
hgs
parents:
diff changeset
    45
#include "d_process_tracker.h"
hgs
parents:
diff changeset
    46
#include "debug_utils.h"
hgs
parents:
diff changeset
    47
hgs
parents:
diff changeset
    48
using namespace Debug;
hgs
parents:
diff changeset
    49
56
hgs
parents: 42
diff changeset
    50
//
42
hgs
parents:
diff changeset
    51
//
hgs
parents:
diff changeset
    52
// DRM_DebugDriverFactory implementation
hgs
parents:
diff changeset
    53
//
56
hgs
parents: 42
diff changeset
    54
//
42
hgs
parents:
diff changeset
    55
hgs
parents:
diff changeset
    56
//
hgs
parents:
diff changeset
    57
// DRM_DebugDriverFactory constructor
hgs
parents:
diff changeset
    58
//
hgs
parents:
diff changeset
    59
DRM_DebugDriverFactory::DRM_DebugDriverFactory()
hgs
parents:
diff changeset
    60
	{
hgs
parents:
diff changeset
    61
	iVersion = TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
hgs
parents:
diff changeset
    62
	}
hgs
parents:
diff changeset
    63
hgs
parents:
diff changeset
    64
//
hgs
parents:
diff changeset
    65
// DRM_DebugDriverFactory::Create
hgs
parents:
diff changeset
    66
//
hgs
parents:
diff changeset
    67
TInt DRM_DebugDriverFactory::Create(DLogicalChannelBase*& aChannel)
hgs
parents:
diff changeset
    68
	{
hgs
parents:
diff changeset
    69
	if (iOpenChannels != 0)
hgs
parents:
diff changeset
    70
		return KErrInUse; // a channel is already open
hgs
parents:
diff changeset
    71
hgs
parents:
diff changeset
    72
	aChannel = new DRM_DebugChannel(this);
hgs
parents:
diff changeset
    73
hgs
parents:
diff changeset
    74
	return aChannel ? KErrNone : KErrNoMemory;
hgs
parents:
diff changeset
    75
	}
hgs
parents:
diff changeset
    76
hgs
parents:
diff changeset
    77
//
hgs
parents:
diff changeset
    78
// DRM_DebugDriverFactory::Install
hgs
parents:
diff changeset
    79
//
hgs
parents:
diff changeset
    80
TInt DRM_DebugDriverFactory::Install()
hgs
parents:
diff changeset
    81
	{
hgs
parents:
diff changeset
    82
	return(SetName(&KRM_DebugDriverName));
hgs
parents:
diff changeset
    83
	}
hgs
parents:
diff changeset
    84
hgs
parents:
diff changeset
    85
//
hgs
parents:
diff changeset
    86
// DRM_DebugDriverFactory::Install
hgs
parents:
diff changeset
    87
//
hgs
parents:
diff changeset
    88
void DRM_DebugDriverFactory::GetCaps(TDes8& aDes) const
hgs
parents:
diff changeset
    89
	{
hgs
parents:
diff changeset
    90
	TCapsRM_DebugDriver b;
hgs
parents:
diff changeset
    91
	b.iVersion = TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildVersionNumber);
hgs
parents:
diff changeset
    92
hgs
parents:
diff changeset
    93
	Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b));
hgs
parents:
diff changeset
    94
	}
hgs
parents:
diff changeset
    95
56
hgs
parents: 42
diff changeset
    96
//
42
hgs
parents:
diff changeset
    97
//
hgs
parents:
diff changeset
    98
// DRM_DebugChannel implementation
hgs
parents:
diff changeset
    99
//
56
hgs
parents: 42
diff changeset
   100
//
42
hgs
parents:
diff changeset
   101
hgs
parents:
diff changeset
   102
//
hgs
parents:
diff changeset
   103
// DRM_DebugChannel constructor
hgs
parents:
diff changeset
   104
//
hgs
parents:
diff changeset
   105
DRM_DebugChannel::DRM_DebugChannel(DLogicalDevice* aLogicalDevice)
hgs
parents:
diff changeset
   106
	: iExcludedROMAddressStart(ROM_LINEAR_BASE),
hgs
parents:
diff changeset
   107
	iExcludedROMAddressEnd(0),
hgs
parents:
diff changeset
   108
	iPageSize(0x1000),
hgs
parents:
diff changeset
   109
	iBreakManager(0),
hgs
parents:
diff changeset
   110
	iStepper(0),
hgs
parents:
diff changeset
   111
	iStepLock(0),
hgs
parents:
diff changeset
   112
	iDfcQ(NULL),
hgs
parents:
diff changeset
   113
	iInitialisedCodeModifier(0),
hgs
parents:
diff changeset
   114
	iAsyncGetValueRequest(NULL)
hgs
parents:
diff changeset
   115
	{
hgs
parents:
diff changeset
   116
	LOG_MSG("DRM_DebugChannel::DRM_DebugChannel()");
hgs
parents:
diff changeset
   117
hgs
parents:
diff changeset
   118
	iDevice = aLogicalDevice;
hgs
parents:
diff changeset
   119
hgs
parents:
diff changeset
   120
	iClientThread = &Kern::CurrentThread();	
hgs
parents:
diff changeset
   121
	
hgs
parents:
diff changeset
   122
	// Opening handle to current thread, so no need to check for return-value
hgs
parents:
diff changeset
   123
	(void)iClientThread->Open();
hgs
parents:
diff changeset
   124
hgs
parents:
diff changeset
   125
	LOG_MSG3("DRM_DebugChannel::DRM_DebugChannel() clientThread = 0x%08x, id=%d", 
hgs
parents:
diff changeset
   126
	            iClientThread, iClientThread->iId );
hgs
parents:
diff changeset
   127
hgs
parents:
diff changeset
   128
hgs
parents:
diff changeset
   129
	iPageSize = Kern::RoundToPageSize(1);
hgs
parents:
diff changeset
   130
	}
hgs
parents:
diff changeset
   131
hgs
parents:
diff changeset
   132
//
hgs
parents:
diff changeset
   133
// DRM_DebugChannel destructor
hgs
parents:
diff changeset
   134
//
hgs
parents:
diff changeset
   135
DRM_DebugChannel::~DRM_DebugChannel()
hgs
parents:
diff changeset
   136
	{
hgs
parents:
diff changeset
   137
	LOG_MSG("DRM_DebugChannel::~DRM_DebugChannel()");
hgs
parents:
diff changeset
   138
hgs
parents:
diff changeset
   139
	if (iAsyncGetValueRequest)
hgs
parents:
diff changeset
   140
		{
hgs
parents:
diff changeset
   141
		Kern::QueueRequestComplete(iClientThread, iAsyncGetValueRequest, KErrCancel); // does nothing if request not pending
hgs
parents:
diff changeset
   142
		Kern::DestroyClientRequest(iAsyncGetValueRequest);
hgs
parents:
diff changeset
   143
		}
hgs
parents:
diff changeset
   144
hgs
parents:
diff changeset
   145
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   146
	Kern::SafeClose((DObject*&)iClientThread, NULL);
hgs
parents:
diff changeset
   147
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   148
hgs
parents:
diff changeset
   149
	// Close breakpoint manager
hgs
parents:
diff changeset
   150
	if (iBreakManager)
hgs
parents:
diff changeset
   151
		{
hgs
parents:
diff changeset
   152
		NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   153
		delete iBreakManager;
hgs
parents:
diff changeset
   154
		NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   155
		}
hgs
parents:
diff changeset
   156
hgs
parents:
diff changeset
   157
	// Close stepping manager
hgs
parents:
diff changeset
   158
	if (iStepper)
hgs
parents:
diff changeset
   159
		{
hgs
parents:
diff changeset
   160
		NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   161
		delete iStepper;
hgs
parents:
diff changeset
   162
		NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   163
		}
hgs
parents:
diff changeset
   164
hgs
parents:
diff changeset
   165
	//close the debug process list
hgs
parents:
diff changeset
   166
	iDebugProcessList.Close();
hgs
parents:
diff changeset
   167
hgs
parents:
diff changeset
   168
	DestroyDfcQ();
hgs
parents:
diff changeset
   169
hgs
parents:
diff changeset
   170
	//close the code modifier
hgs
parents:
diff changeset
   171
	if (iInitialisedCodeModifier)
hgs
parents:
diff changeset
   172
		{
hgs
parents:
diff changeset
   173
		DebugSupport::CloseCodeModifier();
hgs
parents:
diff changeset
   174
		}
hgs
parents:
diff changeset
   175
	}
hgs
parents:
diff changeset
   176
hgs
parents:
diff changeset
   177
void DRM_DebugChannel::DestroyDfcQ()
hgs
parents:
diff changeset
   178
	{
hgs
parents:
diff changeset
   179
	LOG_MSG("DRM_DebugChannel::DestroyDfcQ()");
hgs
parents:
diff changeset
   180
	if (iDfcQ)
hgs
parents:
diff changeset
   181
		{
hgs
parents:
diff changeset
   182
		NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   183
		iDfcQ->Destroy();
hgs
parents:
diff changeset
   184
		NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   185
		}
hgs
parents:
diff changeset
   186
	}
hgs
parents:
diff changeset
   187
hgs
parents:
diff changeset
   188
//
hgs
parents:
diff changeset
   189
// DRM_DebugChannel::DoCreate
hgs
parents:
diff changeset
   190
//
hgs
parents:
diff changeset
   191
TInt DRM_DebugChannel::DoCreate(TInt /*aUnit*/, const TDesC* anInfo, const TVersion& aVer)
hgs
parents:
diff changeset
   192
	{
hgs
parents:
diff changeset
   193
	LOG_MSG("DRM_DebugChannel::DoCreate()");
hgs
parents:
diff changeset
   194
	TInt err = Kern::CreateClientDataRequest(iAsyncGetValueRequest);
hgs
parents:
diff changeset
   195
	if(err != KErrNone)
hgs
parents:
diff changeset
   196
		return err;
hgs
parents:
diff changeset
   197
hgs
parents:
diff changeset
   198
	if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildVersionNumber), aVer))
hgs
parents:
diff changeset
   199
		return KErrNotSupported;
hgs
parents:
diff changeset
   200
hgs
parents:
diff changeset
   201
	// Do the security check here so that any arbitrary application doesn't make
hgs
parents:
diff changeset
   202
	// use of Trk kernel driver.
hgs
parents:
diff changeset
   203
	if (!DoSecurityCheck())
hgs
parents:
diff changeset
   204
		{
hgs
parents:
diff changeset
   205
		LOG_MSG("DRM_DebugChannel::DoCreate() - permission denied!");
hgs
parents:
diff changeset
   206
			return KErrPermissionDenied;
hgs
parents:
diff changeset
   207
		}
hgs
parents:
diff changeset
   208
hgs
parents:
diff changeset
   209
	if (anInfo)
hgs
parents:
diff changeset
   210
		{
hgs
parents:
diff changeset
   211
		// this is the end address of the user library.
hgs
parents:
diff changeset
   212
		// this doesn't seem to be valid for EKA2.
hgs
parents:
diff changeset
   213
		// right now we dont need this for EKA2 since we are not worried
hgs
parents:
diff changeset
   214
		// about kernel being stopped as kernel is multithreaded.
hgs
parents:
diff changeset
   215
		// just retaining this for future use.
hgs
parents:
diff changeset
   216
		TBuf8<32> buf;
hgs
parents:
diff changeset
   217
		TInt err = Kern::ThreadRawRead(iClientThread, anInfo, &buf, 32);
hgs
parents:
diff changeset
   218
		if(err != KErrNone)
hgs
parents:
diff changeset
   219
			return err;
hgs
parents:
diff changeset
   220
		}
hgs
parents:
diff changeset
   221
hgs
parents:
diff changeset
   222
	// Allocate a D_RMD_Breakpoints class as a breakpoint manager
hgs
parents:
diff changeset
   223
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   224
	iBreakManager = new D_RMD_Breakpoints(this);
hgs
parents:
diff changeset
   225
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   226
	if (iBreakManager == NULL)
hgs
parents:
diff changeset
   227
		{
hgs
parents:
diff changeset
   228
		LOG_MSG("DRM_DebugChannel::DRM_DebugChannel - could not construct breakpoint manager");
hgs
parents:
diff changeset
   229
		return KErrNoMemory;
hgs
parents:
diff changeset
   230
		}
hgs
parents:
diff changeset
   231
hgs
parents:
diff changeset
   232
	// Initialise the new breakpoint manager object
hgs
parents:
diff changeset
   233
	iBreakManager->Init();
hgs
parents:
diff changeset
   234
hgs
parents:
diff changeset
   235
	// Allocate a DRMDStepping class as the stepping manager
hgs
parents:
diff changeset
   236
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   237
	iStepper = new DRMDStepping(this);
hgs
parents:
diff changeset
   238
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   239
	if (iStepper == NULL)
hgs
parents:
diff changeset
   240
		{
hgs
parents:
diff changeset
   241
		LOG_MSG("DRM_DebugChannel::DRM_DebugChannel - could not construct stepper manager");
hgs
parents:
diff changeset
   242
		return KErrNoMemory;
hgs
parents:
diff changeset
   243
		}
hgs
parents:
diff changeset
   244
hgs
parents:
diff changeset
   245
	// Initialize the code modifier for managing breakpoints.
hgs
parents:
diff changeset
   246
	TUint caps; //ignored for now
hgs
parents:
diff changeset
   247
	err = DebugSupport::InitialiseCodeModifier(caps, NUMBER_OF_MAX_BREAKPOINTS);
hgs
parents:
diff changeset
   248
	//if code modifier initializer failed,
hgs
parents:
diff changeset
   249
	//return here, since we can't set an breakpoints
hgs
parents:
diff changeset
   250
	if(err != KErrNone)
hgs
parents:
diff changeset
   251
		{
hgs
parents:
diff changeset
   252
		return err;
hgs
parents:
diff changeset
   253
		}
hgs
parents:
diff changeset
   254
	else
hgs
parents:
diff changeset
   255
		{
hgs
parents:
diff changeset
   256
		iInitialisedCodeModifier = ETrue;
hgs
parents:
diff changeset
   257
		}
hgs
parents:
diff changeset
   258
hgs
parents:
diff changeset
   259
	//create and set the driver's Dfc queue
hgs
parents:
diff changeset
   260
	err = CreateDfcQ();
hgs
parents:
diff changeset
   261
	if(err != KErrNone)
hgs
parents:
diff changeset
   262
		{
hgs
parents:
diff changeset
   263
		LOG_MSG("DRM_DebugChannel::DoCreate() Creating Dfc queue failed.");
hgs
parents:
diff changeset
   264
		}
hgs
parents:
diff changeset
   265
	SetDfcQ(iDfcQ);
hgs
parents:
diff changeset
   266
hgs
parents:
diff changeset
   267
	iMsgQ.Receive();
hgs
parents:
diff changeset
   268
hgs
parents:
diff changeset
   269
	iEventHandler = new DRM_DebugEventHandler;
hgs
parents:
diff changeset
   270
	if (!iEventHandler)
hgs
parents:
diff changeset
   271
		return KErrNoMemory;
hgs
parents:
diff changeset
   272
	err = iEventHandler->Create(iDevice, this, iClientThread);
hgs
parents:
diff changeset
   273
	if (err != KErrNone)
hgs
parents:
diff changeset
   274
		return err;
hgs
parents:
diff changeset
   275
hgs
parents:
diff changeset
   276
	//return KErrNone;
hgs
parents:
diff changeset
   277
	return iEventHandler->Start();
hgs
parents:
diff changeset
   278
	}
hgs
parents:
diff changeset
   279
hgs
parents:
diff changeset
   280
/**
hgs
parents:
diff changeset
   281
Forward call to either synch or asynch methods while serialising all calls via lock.
hgs
parents:
diff changeset
   282
 
hgs
parents:
diff changeset
   283
Protect access via a the event handler lock to 
hgs
parents:
diff changeset
   284
serialise all calls and protect concurrent access to data structures
hgs
parents:
diff changeset
   285
hgs
parents:
diff changeset
   286
@param aMsg pointer to a TMessageBase object 
hgs
parents:
diff changeset
   287
hgs
parents:
diff changeset
   288
@return error returned by called methods
hgs
parents:
diff changeset
   289
hgs
parents:
diff changeset
   290
@see DRM_DebugEventHandler::HandleSpecificEvent where lock is also used
hgs
parents:
diff changeset
   291
@see DRM_DebugEventHandler::iProtectionLock
hgs
parents:
diff changeset
   292
hgs
parents:
diff changeset
   293
*/
hgs
parents:
diff changeset
   294
TInt DRM_DebugChannel::SendMsg(TMessageBase* aMsg)
hgs
parents:
diff changeset
   295
	{
hgs
parents:
diff changeset
   296
	DThread * currThread = &Kern::CurrentThread();
hgs
parents:
diff changeset
   297
hgs
parents:
diff changeset
   298
	iEventHandler->LockDataAccess();
hgs
parents:
diff changeset
   299
	LOG_MSG3("DRM_DebugChannel::SendMsg() currThread = 0x%08x, iClientThread=0x%08x", currThread, iClientThread );
hgs
parents:
diff changeset
   300
	
hgs
parents:
diff changeset
   301
	TThreadMessage& m = *(TThreadMessage*)aMsg;
hgs
parents:
diff changeset
   302
	TInt id = m.iValue;
hgs
parents:
diff changeset
   303
	TInt err = KErrNone;
hgs
parents:
diff changeset
   304
hgs
parents:
diff changeset
   305
	if (id != (TInt)ECloseMsg && id != KMaxTInt && id < 0)
hgs
parents:
diff changeset
   306
		{
hgs
parents:
diff changeset
   307
		// DoRequest
hgs
parents:
diff changeset
   308
		TRequestStatus* pStatus = (TRequestStatus*)m.Ptr0();
hgs
parents:
diff changeset
   309
		err = SendRequest(aMsg);
hgs
parents:
diff changeset
   310
		if (err != KErrNone)
hgs
parents:
diff changeset
   311
			Kern::RequestComplete(pStatus,err);
hgs
parents:
diff changeset
   312
		}
hgs
parents:
diff changeset
   313
	else
hgs
parents:
diff changeset
   314
		{
hgs
parents:
diff changeset
   315
		err = DLogicalChannel::SendMsg(aMsg);
hgs
parents:
diff changeset
   316
		}
hgs
parents:
diff changeset
   317
	
hgs
parents:
diff changeset
   318
	iEventHandler->ReleaseDataAccess();
hgs
parents:
diff changeset
   319
	return err;
hgs
parents:
diff changeset
   320
	}
hgs
parents:
diff changeset
   321
hgs
parents:
diff changeset
   322
//
hgs
parents:
diff changeset
   323
// DRM_DebugChannel::SendRequest
hgs
parents:
diff changeset
   324
//
hgs
parents:
diff changeset
   325
TInt DRM_DebugChannel::SendRequest(TMessageBase* aMsg)
hgs
parents:
diff changeset
   326
	{
hgs
parents:
diff changeset
   327
	LOG_MSG("DRM_DebugChannel::SendRequest()");
hgs
parents:
diff changeset
   328
hgs
parents:
diff changeset
   329
	TThreadMessage& m = *(TThreadMessage*)aMsg;
hgs
parents:
diff changeset
   330
	TInt function = ~m.iValue;
hgs
parents:
diff changeset
   331
	TRequestStatus* pStatus = (TRequestStatus*)m.Ptr0();
hgs
parents:
diff changeset
   332
	TAny* a1 = m.Ptr1();
hgs
parents:
diff changeset
   333
hgs
parents:
diff changeset
   334
	TInt err = KErrNotSupported;
hgs
parents:
diff changeset
   335
	switch(function)
hgs
parents:
diff changeset
   336
		{
hgs
parents:
diff changeset
   337
		case RRM_DebugDriver::ERequestGetEvent:
hgs
parents:
diff changeset
   338
			err = PreAsyncGetValue((TEventInfo*)a1,pStatus);
hgs
parents:
diff changeset
   339
			break;
hgs
parents:
diff changeset
   340
		}
hgs
parents:
diff changeset
   341
	if (err == KErrNone)
hgs
parents:
diff changeset
   342
		err = DLogicalChannel::SendMsg(aMsg);
hgs
parents:
diff changeset
   343
	return err;
hgs
parents:
diff changeset
   344
	}
hgs
parents:
diff changeset
   345
hgs
parents:
diff changeset
   346
//
hgs
parents:
diff changeset
   347
// DRM_DebugChannel::PreAsyncGetValue
hgs
parents:
diff changeset
   348
//
hgs
parents:
diff changeset
   349
TInt DRM_DebugChannel::PreAsyncGetValue(TEventInfo* aValue, TRequestStatus* aStatus)
hgs
parents:
diff changeset
   350
	{
hgs
parents:
diff changeset
   351
	LOG_MSG3("DRM_DebugChannel::PreAsyncGetValue() TEventInfo=0x%08x, TRequestStatus=0x%08x",
hgs
parents:
diff changeset
   352
		aValue, aStatus );
hgs
parents:
diff changeset
   353
	
hgs
parents:
diff changeset
   354
	iAsyncGetValueRequest->Reset();
hgs
parents:
diff changeset
   355
	
hgs
parents:
diff changeset
   356
	TInt err = iAsyncGetValueRequest->SetStatus(aStatus);
hgs
parents:
diff changeset
   357
	if (err != KErrNone)
hgs
parents:
diff changeset
   358
		return err;
hgs
parents:
diff changeset
   359
	
hgs
parents:
diff changeset
   360
	iAsyncGetValueRequest->SetDestPtr(aValue);
hgs
parents:
diff changeset
   361
	return KErrNone;
hgs
parents:
diff changeset
   362
	}
hgs
parents:
diff changeset
   363
hgs
parents:
diff changeset
   364
/**
hgs
parents:
diff changeset
   365
  Create the Dfc queue for receiving messages
hgs
parents:
diff changeset
   366
  */
hgs
parents:
diff changeset
   367
TInt DRM_DebugChannel::CreateDfcQ()
hgs
parents:
diff changeset
   368
	{
hgs
parents:
diff changeset
   369
	LOG_MSG("DRM_DebugChannel::CreateDfcQ()");
hgs
parents:
diff changeset
   370
	TInt r = Kern::DynamicDfcQCreate(iDfcQ, KRmDebugDriverThreadPriority, KRM_DebugDriverName);
hgs
parents:
diff changeset
   371
hgs
parents:
diff changeset
   372
	if (r == KErrNone)
hgs
parents:
diff changeset
   373
		iDfcQ->SetRealtimeState(ERealtimeStateOff);
hgs
parents:
diff changeset
   374
	return r;
hgs
parents:
diff changeset
   375
	}
hgs
parents:
diff changeset
   376
hgs
parents:
diff changeset
   377
//
hgs
parents:
diff changeset
   378
// DRM_DebugChannel::DoCancel
hgs
parents:
diff changeset
   379
//
hgs
parents:
diff changeset
   380
// New: The cancel call does not take an enum parameter describing
hgs
parents:
diff changeset
   381
// the request to be cancelled. Rather it supplies a pointer
hgs
parents:
diff changeset
   382
// to a user-side struct defining the cancellation
hgs
parents:
diff changeset
   383
//
hgs
parents:
diff changeset
   384
void DRM_DebugChannel::DoCancel(TInt aReqNo)
hgs
parents:
diff changeset
   385
	{
hgs
parents:
diff changeset
   386
	LOG_MSG("DRM_DebugChannel::DoCancel()");
hgs
parents:
diff changeset
   387
hgs
parents:
diff changeset
   388
	TRMD_DebugCancelInfo info;
hgs
parents:
diff changeset
   389
hgs
parents:
diff changeset
   390
	TInt err = Kern::ThreadRawRead(iClientThread,(TAny*)aReqNo,(TAny*)&info,sizeof(info));
hgs
parents:
diff changeset
   391
	if (err != KErrNone)
hgs
parents:
diff changeset
   392
		{
hgs
parents:
diff changeset
   393
		// How do we cancel something we know nothing about???
hgs
parents:
diff changeset
   394
		LOG_MSG("DRM_DebugChannel::DoCancel - bad arguments");
hgs
parents:
diff changeset
   395
		return;
hgs
parents:
diff changeset
   396
		}
hgs
parents:
diff changeset
   397
hgs
parents:
diff changeset
   398
	DDebugAgent* debugAgent = TheDProcessTracker.FindAgentForProcessAndId(info.iProcessName, info.iAgentId);
hgs
parents:
diff changeset
   399
	if (debugAgent == NULL)
hgs
parents:
diff changeset
   400
		{
hgs
parents:
diff changeset
   401
		// Bad agent means there is no tracking agent
hgs
parents:
diff changeset
   402
		LOG_MSG2("Cannot locate debug agent with pid 0x%x", info.iAgentId);
hgs
parents:
diff changeset
   403
		return;
hgs
parents:
diff changeset
   404
		}
hgs
parents:
diff changeset
   405
hgs
parents:
diff changeset
   406
	// Agent completes/pends the request as appropriate.
hgs
parents:
diff changeset
   407
	debugAgent->CancelGetEvent();
hgs
parents:
diff changeset
   408
hgs
parents:
diff changeset
   409
	}
hgs
parents:
diff changeset
   410
hgs
parents:
diff changeset
   411
//
hgs
parents:
diff changeset
   412
// DRM_DebugChannel::DoRequest
hgs
parents:
diff changeset
   413
//
hgs
parents:
diff changeset
   414
void DRM_DebugChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2)
hgs
parents:
diff changeset
   415
	{
hgs
parents:
diff changeset
   416
	LOG_MSG4("DRM_DebugChannel::DoRequest(), iClientThread=0x%08x, tid=0x%08x, TRequestStatus=0x%08x", 
hgs
parents:
diff changeset
   417
		iClientThread, I64LOW(iClientThread->iId), aStatus);
hgs
parents:
diff changeset
   418
hgs
parents:
diff changeset
   419
	switch(aReqNo)
hgs
parents:
diff changeset
   420
		{
hgs
parents:
diff changeset
   421
		case RRM_DebugDriver::ERequestGetEvent:
hgs
parents:
diff changeset
   422
			{
hgs
parents:
diff changeset
   423
			TEventMetaData eventMetaData;
hgs
parents:
diff changeset
   424
			TInt err = Kern::ThreadRawRead(iClientThread, a2, (TUint8 *)&eventMetaData, sizeof(TEventMetaData) );
hgs
parents:
diff changeset
   425
			if (err != KErrNone)
hgs
parents:
diff changeset
   426
				{
hgs
parents:
diff changeset
   427
				LOG_MSG("Error: could not read argument data from the DSS (TEventMetaData)");
hgs
parents:
diff changeset
   428
hgs
parents:
diff changeset
   429
				// We could not read information from the user, so the a2 argument is probably wrong
hgs
parents:
diff changeset
   430
				Kern::RequestComplete(iClientThread, aStatus, KErrArgument);
hgs
parents:
diff changeset
   431
				return;
hgs
parents:
diff changeset
   432
				}
hgs
parents:
diff changeset
   433
hgs
parents:
diff changeset
   434
			DDebugAgent* debugAgent = TheDProcessTracker.FindAgentForProcessAndId(eventMetaData.iTargetProcessName, eventMetaData.iDebugAgentProcessId);
hgs
parents:
diff changeset
   435
			if (debugAgent == NULL)
hgs
parents:
diff changeset
   436
				{
hgs
parents:
diff changeset
   437
				// Bad agent means there is no tracking agent
hgs
parents:
diff changeset
   438
				LOG_MSG2("Cannot locate debug agent with pid 0x%x", eventMetaData.iDebugAgentProcessId);
hgs
parents:
diff changeset
   439
				Kern::RequestComplete(iClientThread, aStatus, KErrNotFound);
hgs
parents:
diff changeset
   440
				return;
hgs
parents:
diff changeset
   441
				}
hgs
parents:
diff changeset
   442
			// Agent completes/pends the request as appropriate.
hgs
parents:
diff changeset
   443
			debugAgent->GetEvent(iAsyncGetValueRequest, iClientThread);
hgs
parents:
diff changeset
   444
hgs
parents:
diff changeset
   445
			break;
hgs
parents:
diff changeset
   446
			}
hgs
parents:
diff changeset
   447
		default:
hgs
parents:
diff changeset
   448
			{
hgs
parents:
diff changeset
   449
			// Should not get here!
hgs
parents:
diff changeset
   450
			LOG_MSG2("DRM_DebugChannel::DoRequest was passed unsupported request aReqNo=%d", aReqNo );
hgs
parents:
diff changeset
   451
			Kern::RequestComplete(iClientThread, aStatus, KErrNotSupported);
hgs
parents:
diff changeset
   452
			}
hgs
parents:
diff changeset
   453
		}
hgs
parents:
diff changeset
   454
	}
hgs
parents:
diff changeset
   455
hgs
parents:
diff changeset
   456
//
hgs
parents:
diff changeset
   457
// DRM_DebugChannel::DoControl
hgs
parents:
diff changeset
   458
//
hgs
parents:
diff changeset
   459
TInt DRM_DebugChannel::DoControl(TInt aFunction, TAny* a1, TAny* a2)
hgs
parents:
diff changeset
   460
	{
hgs
parents:
diff changeset
   461
	LOG_MSG("DRM_DebugChannel::DoControl()");
hgs
parents:
diff changeset
   462
hgs
parents:
diff changeset
   463
	LOG_MSG2("DoControl Function %d", aFunction);
hgs
parents:
diff changeset
   464
hgs
parents:
diff changeset
   465
	TInt err = KErrNone;
hgs
parents:
diff changeset
   466
	DThread* threadObj = NULL;
hgs
parents:
diff changeset
   467
	// Open a thread handle for the operations that need one
hgs
parents:
diff changeset
   468
	switch (aFunction)
hgs
parents:
diff changeset
   469
		{
hgs
parents:
diff changeset
   470
		case RRM_DebugDriver::EControlSuspendThread:
hgs
parents:
diff changeset
   471
		case RRM_DebugDriver::EControlResumeThread:
hgs
parents:
diff changeset
   472
		case RRM_DebugDriver::EControlStepRange:
hgs
parents:
diff changeset
   473
		case RRM_DebugDriver::EControlReadMemory:
hgs
parents:
diff changeset
   474
		case RRM_DebugDriver::EControlWriteMemory:
hgs
parents:
diff changeset
   475
		case RRM_DebugDriver::EControlReadRegistersLegacy:
hgs
parents:
diff changeset
   476
		case RRM_DebugDriver::EControlWriteRegistersLegacy:
hgs
parents:
diff changeset
   477
		case RRM_DebugDriver::EControlReadRegisters:
hgs
parents:
diff changeset
   478
		case RRM_DebugDriver::EControlWriteRegisters:
hgs
parents:
diff changeset
   479
			{
hgs
parents:
diff changeset
   480
			NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   481
			threadObj = DebugUtils::OpenThreadHandle((TUint32)a1);
hgs
parents:
diff changeset
   482
			if (!threadObj)
hgs
parents:
diff changeset
   483
				{
hgs
parents:
diff changeset
   484
				NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   485
				return KErrBadHandle;
hgs
parents:
diff changeset
   486
				}
hgs
parents:
diff changeset
   487
			break;
hgs
parents:
diff changeset
   488
			}
hgs
parents:
diff changeset
   489
		default:
hgs
parents:
diff changeset
   490
			break;
hgs
parents:
diff changeset
   491
		}
hgs
parents:
diff changeset
   492
hgs
parents:
diff changeset
   493
	switch(aFunction)
hgs
parents:
diff changeset
   494
		{
hgs
parents:
diff changeset
   495
		/* Security first */
hgs
parents:
diff changeset
   496
		case RRM_DebugDriver::EControlIsDebuggable:
hgs
parents:
diff changeset
   497
			{
hgs
parents:
diff changeset
   498
			err = IsDebuggable((TUint32)a1);
hgs
parents:
diff changeset
   499
			break;
hgs
parents:
diff changeset
   500
			}
hgs
parents:
diff changeset
   501
		case RRM_DebugDriver::EControlSetBreak:
hgs
parents:
diff changeset
   502
			{
hgs
parents:
diff changeset
   503
			err = SetBreak((TSetBreakInfo*)a1);
hgs
parents:
diff changeset
   504
			break;
hgs
parents:
diff changeset
   505
			}
hgs
parents:
diff changeset
   506
		case RRM_DebugDriver::EControlClearBreak:
hgs
parents:
diff changeset
   507
			{
hgs
parents:
diff changeset
   508
			err = iBreakManager->DoClearBreak((TInt32)a1);
hgs
parents:
diff changeset
   509
			break;
hgs
parents:
diff changeset
   510
			}
hgs
parents:
diff changeset
   511
		case RRM_DebugDriver::EControlModifyBreak:
hgs
parents:
diff changeset
   512
			{
hgs
parents:
diff changeset
   513
			err = iBreakManager->DoModifyBreak((TModifyBreakInfo*)a1);
hgs
parents:
diff changeset
   514
			break;
hgs
parents:
diff changeset
   515
			}
hgs
parents:
diff changeset
   516
		case RRM_DebugDriver::EControlModifyProcessBreak:
hgs
parents:
diff changeset
   517
			{
hgs
parents:
diff changeset
   518
			err = iBreakManager->DoModifyProcessBreak((TModifyProcessBreakInfo*)a1);
hgs
parents:
diff changeset
   519
			break;
hgs
parents:
diff changeset
   520
			}
hgs
parents:
diff changeset
   521
		case RRM_DebugDriver::EControlBreakInfo:
hgs
parents:
diff changeset
   522
			{
hgs
parents:
diff changeset
   523
			err = iBreakManager->DoBreakInfo((TGetBreakInfo*)a1);
hgs
parents:
diff changeset
   524
			break;
hgs
parents:
diff changeset
   525
			}
hgs
parents:
diff changeset
   526
		case RRM_DebugDriver::EControlSuspendThread:
hgs
parents:
diff changeset
   527
			{
hgs
parents:
diff changeset
   528
			err = DoSuspendThread(threadObj);
hgs
parents:
diff changeset
   529
			break;
hgs
parents:
diff changeset
   530
			}
hgs
parents:
diff changeset
   531
		case RRM_DebugDriver::EControlResumeThread:
hgs
parents:
diff changeset
   532
			{
hgs
parents:
diff changeset
   533
			err = DoResumeThread(threadObj);
hgs
parents:
diff changeset
   534
			break;
hgs
parents:
diff changeset
   535
			}
hgs
parents:
diff changeset
   536
		case RRM_DebugDriver::EControlStepRange:
hgs
parents:
diff changeset
   537
			{
hgs
parents:
diff changeset
   538
			err = StepRange(threadObj, (TRM_DebugStepInfo*)a2);
hgs
parents:
diff changeset
   539
			break;
hgs
parents:
diff changeset
   540
			}
hgs
parents:
diff changeset
   541
		case RRM_DebugDriver::EControlReadMemory:
hgs
parents:
diff changeset
   542
			{
hgs
parents:
diff changeset
   543
			err = ReadMemory(threadObj, (TRM_DebugMemoryInfo*)a2);
hgs
parents:
diff changeset
   544
			break;
hgs
parents:
diff changeset
   545
			}
hgs
parents:
diff changeset
   546
		case RRM_DebugDriver::EControlWriteMemory:
hgs
parents:
diff changeset
   547
			{
hgs
parents:
diff changeset
   548
			err = WriteMemory(threadObj, (TRM_DebugMemoryInfo*)a2);
hgs
parents:
diff changeset
   549
			break;
hgs
parents:
diff changeset
   550
			}
hgs
parents:
diff changeset
   551
		case RRM_DebugDriver::EControlReadRegistersLegacy:
hgs
parents:
diff changeset
   552
			{
hgs
parents:
diff changeset
   553
			err = ReadRegistersLegacy(threadObj, (TRM_DebugRegisterInfo*)a2);
hgs
parents:
diff changeset
   554
			break;
hgs
parents:
diff changeset
   555
			}
hgs
parents:
diff changeset
   556
		case RRM_DebugDriver::EControlWriteRegistersLegacy:
hgs
parents:
diff changeset
   557
			{
hgs
parents:
diff changeset
   558
			err = WriteRegistersLegacy(threadObj, (TRM_DebugRegisterInfo*)a2);
hgs
parents:
diff changeset
   559
			break;
hgs
parents:
diff changeset
   560
			}
hgs
parents:
diff changeset
   561
		case RRM_DebugDriver::EControlReadRegisters:
hgs
parents:
diff changeset
   562
			{
hgs
parents:
diff changeset
   563
			err = ReadRegisters(threadObj, (TRM_DebugRegisterInformation*)a2);
hgs
parents:
diff changeset
   564
			break;
hgs
parents:
diff changeset
   565
			}
hgs
parents:
diff changeset
   566
		case RRM_DebugDriver::EControlWriteRegisters:
hgs
parents:
diff changeset
   567
			{
hgs
parents:
diff changeset
   568
			err = WriteRegisters(threadObj, (TRM_DebugRegisterInformation*)a2);
hgs
parents:
diff changeset
   569
			break;
hgs
parents:
diff changeset
   570
			}
hgs
parents:
diff changeset
   571
		case RRM_DebugDriver::EControlGetDebugFunctionalityBufSize:
hgs
parents:
diff changeset
   572
			{
hgs
parents:
diff changeset
   573
			LOG_MSG("RRM_DebugDriver::EControlGetDebugFunctionalityBufSize\n");
hgs
parents:
diff changeset
   574
hgs
parents:
diff changeset
   575
			TDebugFunctionality df;
hgs
parents:
diff changeset
   576
hgs
parents:
diff changeset
   577
			TUint size = df.GetDebugFunctionalityBufSize();
hgs
parents:
diff changeset
   578
hgs
parents:
diff changeset
   579
			// Return size to user-side in a safe manner
hgs
parents:
diff changeset
   580
			err = Kern::ThreadRawWrite(iClientThread, a1, (TUint8*)&size, sizeof(TUint), iClientThread);
hgs
parents:
diff changeset
   581
			break;
hgs
parents:
diff changeset
   582
			}
hgs
parents:
diff changeset
   583
		case RRM_DebugDriver::EControlGetDebugFunctionality:
hgs
parents:
diff changeset
   584
			{
hgs
parents:
diff changeset
   585
			LOG_MSG("RRM_DebugDriver::EControlGetDebugFunctionality\n");
hgs
parents:
diff changeset
   586
hgs
parents:
diff changeset
   587
			TDebugFunctionality df;
hgs
parents:
diff changeset
   588
hgs
parents:
diff changeset
   589
			TUint32 dfsize = df.GetDebugFunctionalityBufSize();
hgs
parents:
diff changeset
   590
hgs
parents:
diff changeset
   591
			// Alloc tmp buffer for Debug Functionality data
hgs
parents:
diff changeset
   592
			NKern::ThreadEnterCS();
hgs
parents:
diff changeset
   593
			TUint8* dfbuffer = (TUint8*)Kern::AllocZ(dfsize);
hgs
parents:
diff changeset
   594
			if (dfbuffer==NULL)
hgs
parents:
diff changeset
   595
				{
hgs
parents:
diff changeset
   596
				LOG_MSG2("Could not allocate memory for %d bytes\n",dfsize);
hgs
parents:
diff changeset
   597
				NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   598
				// could not allocate memory
hgs
parents:
diff changeset
   599
				return KErrNoMemory;
hgs
parents:
diff changeset
   600
				}
hgs
parents:
diff changeset
   601
hgs
parents:
diff changeset
   602
			// Temporary descriptor to hold DF data
hgs
parents:
diff changeset
   603
			TPtr8 tmpPtr(dfbuffer,0,dfsize);
hgs
parents:
diff changeset
   604
hgs
parents:
diff changeset
   605
			// Obtain the DF data
hgs
parents:
diff changeset
   606
			if (df.GetDebugFunctionality(tmpPtr) )
hgs
parents:
diff changeset
   607
				{
hgs
parents:
diff changeset
   608
				// Return the DF data to the user-side
hgs
parents:
diff changeset
   609
				err = Kern::ThreadDesWrite(iClientThread, a1, tmpPtr, 0, KChunkShiftBy0, iClientThread);
hgs
parents:
diff changeset
   610
				}
hgs
parents:
diff changeset
   611
			else
hgs
parents:
diff changeset
   612
				{
hgs
parents:
diff changeset
   613
				// Failed.
hgs
parents:
diff changeset
   614
				err = KErrGeneral;
hgs
parents:
diff changeset
   615
				}
hgs
parents:
diff changeset
   616
hgs
parents:
diff changeset
   617
			// Free tmp buffer
hgs
parents:
diff changeset
   618
			Kern::Free(dfbuffer);
hgs
parents:
diff changeset
   619
			NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   620
			break;
hgs
parents:
diff changeset
   621
			}
hgs
parents:
diff changeset
   622
		case RRM_DebugDriver::EControlAttachProcess:
hgs
parents:
diff changeset
   623
			{
hgs
parents:
diff changeset
   624
			LOG_MSG("RRM_DebugDriver::EControlAttachProcess");
hgs
parents:
diff changeset
   625
hgs
parents:
diff changeset
   626
			err = AttachProcess(a1,a2);
hgs
parents:
diff changeset
   627
			break;
hgs
parents:
diff changeset
   628
			}
hgs
parents:
diff changeset
   629
		case RRM_DebugDriver::EControlDetachProcess:
hgs
parents:
diff changeset
   630
			{
hgs
parents:
diff changeset
   631
			LOG_MSG("RRM_DebugDriver::EControlDetachProcess");
hgs
parents:
diff changeset
   632
hgs
parents:
diff changeset
   633
			err = DetachProcess(a1,a2);
hgs
parents:
diff changeset
   634
			break;
hgs
parents:
diff changeset
   635
			}
hgs
parents:
diff changeset
   636
		case RRM_DebugDriver::EControlDetachAgent:
hgs
parents:
diff changeset
   637
			{
hgs
parents:
diff changeset
   638
			LOG_MSG("RRM_DebugDriver::EControlDetachAgent");
hgs
parents:
diff changeset
   639
hgs
parents:
diff changeset
   640
			err = DetachAgent(a1,a2);
hgs
parents:
diff changeset
   641
			break;
hgs
parents:
diff changeset
   642
			}
hgs
parents:
diff changeset
   643
		case RRM_DebugDriver::EControlSetEventAction:
hgs
parents:
diff changeset
   644
			{
hgs
parents:
diff changeset
   645
			LOG_MSG("RRM_DebugDriver::EControlSetEventAction");
hgs
parents:
diff changeset
   646
hgs
parents:
diff changeset
   647
			err = SetEventAction(a1,a2);
hgs
parents:
diff changeset
   648
			break;
hgs
parents:
diff changeset
   649
			}
hgs
parents:
diff changeset
   650
		case RRM_DebugDriver::EControlGetMemoryOperationMaxBlockSize:
hgs
parents:
diff changeset
   651
			{
hgs
parents:
diff changeset
   652
			LOG_MSG("RRM_DebugDriver::EControlGetMemoryOperationMaxBlockSize\n");
hgs
parents:
diff changeset
   653
hgs
parents:
diff changeset
   654
			TUint32 maxSize = TDebugFunctionality::GetMemoryOperationMaxBlockSize();
hgs
parents:
diff changeset
   655
hgs
parents:
diff changeset
   656
			// Return size to user-side in a safe manner
hgs
parents:
diff changeset
   657
			err = Kern::ThreadRawWrite(iClientThread, a1, (TUint8*)&maxSize, sizeof(TUint32), iClientThread);
hgs
parents:
diff changeset
   658
			break;
hgs
parents:
diff changeset
   659
			}
hgs
parents:
diff changeset
   660
		case RRM_DebugDriver::EControlGetList:
hgs
parents:
diff changeset
   661
			{
hgs
parents:
diff changeset
   662
			LOG_MSG("RRM_DebugDriver::EControlGetList\n");
hgs
parents:
diff changeset
   663
			err = GetList((TListInformation*)a1);
hgs
parents:
diff changeset
   664
			break;
hgs
parents:
diff changeset
   665
			}
hgs
parents:
diff changeset
   666
		case RRM_DebugDriver::EControlStep:
hgs
parents:
diff changeset
   667
			{
hgs
parents:
diff changeset
   668
			LOG_MSG("RRM_DebugDriver::EControlStep\n");
hgs
parents:
diff changeset
   669
hgs
parents:
diff changeset
   670
			err = Step((TUint32)a1,(TUint32)a2);
hgs
parents:
diff changeset
   671
			break;
hgs
parents:
diff changeset
   672
			}
hgs
parents:
diff changeset
   673
		case RRM_DebugDriver::EControlKillProcess:
hgs
parents:
diff changeset
   674
			{
hgs
parents:
diff changeset
   675
			LOG_MSG("RRM_DebugDriver::EControlKillProcess\n");
hgs
parents:
diff changeset
   676
hgs
parents:
diff changeset
   677
			err = KillProcess((TUint32)a1,(TUint32)a2);
hgs
parents:
diff changeset
   678
			break;
hgs
parents:
diff changeset
   679
			}
hgs
parents:
diff changeset
   680
		default:
hgs
parents:
diff changeset
   681
			{
hgs
parents:
diff changeset
   682
			err = KErrGeneral;
hgs
parents:
diff changeset
   683
			}
hgs
parents:
diff changeset
   684
		}
hgs
parents:
diff changeset
   685
hgs
parents:
diff changeset
   686
	if (KErrNone != err)
hgs
parents:
diff changeset
   687
		{
hgs
parents:
diff changeset
   688
		LOG_MSG2("Error %d from control function", err);
hgs
parents:
diff changeset
   689
		}
hgs
parents:
diff changeset
   690
hgs
parents:
diff changeset
   691
	if (threadObj)
hgs
parents:
diff changeset
   692
		{
hgs
parents:
diff changeset
   693
		// Close the thread handle which has been opened by DebugUtils::OpenThreadHandle
hgs
parents:
diff changeset
   694
		threadObj->Close(NULL);
hgs
parents:
diff changeset
   695
		NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
   696
		}
hgs
parents:
diff changeset
   697
hgs
parents:
diff changeset
   698
	return err;
hgs
parents:
diff changeset
   699
	}
hgs
parents:
diff changeset
   700
hgs
parents:
diff changeset
   701
void DRM_DebugChannel::HandleMsg(TMessageBase* aMsg)
hgs
parents:
diff changeset
   702
	{
hgs
parents:
diff changeset
   703
	LOG_MSG("DRM_DebugChannel::HandleMsg()");
hgs
parents:
diff changeset
   704
hgs
parents:
diff changeset
   705
	TThreadMessage& m = *(TThreadMessage*)aMsg;
hgs
parents:
diff changeset
   706
	TInt id = m.iValue;
hgs
parents:
diff changeset
   707
hgs
parents:
diff changeset
   708
	if (id == (TInt)ECloseMsg)
hgs
parents:
diff changeset
   709
		{
hgs
parents:
diff changeset
   710
		if (iEventHandler)
hgs
parents:
diff changeset
   711
			{
hgs
parents:
diff changeset
   712
			iEventHandler->Stop();
hgs
parents:
diff changeset
   713
			iEventHandler->Close();
hgs
parents:
diff changeset
   714
			iEventHandler = NULL;
hgs
parents:
diff changeset
   715
			}
hgs
parents:
diff changeset
   716
		m.Complete(KErrNone, EFalse);
hgs
parents:
diff changeset
   717
		return;
hgs
parents:
diff changeset
   718
		}
hgs
parents:
diff changeset
   719
hgs
parents:
diff changeset
   720
	if (id == KMaxTInt)
hgs
parents:
diff changeset
   721
		{
hgs
parents:
diff changeset
   722
		// DoCancel
hgs
parents:
diff changeset
   723
		DoCancel(m.Int0());
hgs
parents:
diff changeset
   724
		m.Complete(KErrNone, ETrue);
hgs
parents:
diff changeset
   725
		return;
hgs
parents:
diff changeset
   726
		}
hgs
parents:
diff changeset
   727
hgs
parents:
diff changeset
   728
	if (id < 0)
hgs
parents:
diff changeset
   729
		{
hgs
parents:
diff changeset
   730
		// DoRequest
hgs
parents:
diff changeset
   731
		TRequestStatus* pStatus = (TRequestStatus*)m.Ptr0();
hgs
parents:
diff changeset
   732
		DoRequest(~id, pStatus, m.Ptr1(), m.Ptr2());
hgs
parents:
diff changeset
   733
		m.Complete(KErrNone, ETrue);
hgs
parents:
diff changeset
   734
		}
hgs
parents:
diff changeset
   735
	else
hgs
parents:
diff changeset
   736
		{
hgs
parents:
diff changeset
   737
		// DoControl
hgs
parents:
diff changeset
   738
		TInt err = DoControl(id, m.Ptr0(), m.Ptr1());
hgs
parents:
diff changeset
   739
		m.Complete(err, ETrue);
hgs
parents:
diff changeset
   740
		}
hgs
parents:
diff changeset
   741
	}
hgs
parents:
diff changeset
   742
hgs
parents:
diff changeset
   743
//
hgs
parents:
diff changeset
   744
// DRM_DebugChannel::RemoveProcess
hgs
parents:
diff changeset
   745
//
hgs
parents:
diff changeset
   746
TBool DRM_DebugChannel::RemoveProcess(TAny* a1, TAny* a2)
hgs
parents:
diff changeset
   747
	{
hgs
parents:
diff changeset
   748
	LOG_MSG("DRM_DebugChannel::RemoveProcess()");
hgs
parents:
diff changeset
   749
hgs
parents:
diff changeset
   750
	DProcess *aProcess = (DProcess*)a1;
hgs
parents:
diff changeset
   751
hgs
parents:
diff changeset
   752
	// Sanity check
hgs
parents:
diff changeset
   753
	if (!aProcess)
hgs
parents:
diff changeset
   754
		{
hgs
parents:
diff changeset
   755
		// No process was specified!
hgs
parents:
diff changeset
   756
		LOG_MSG("DRM_DebugChannel::RemoveProcess was called with an invalid process ID");
hgs
parents:
diff changeset
   757
		return EFalse;
hgs
parents:
diff changeset
   758
		}
hgs
parents:
diff changeset
   759
hgs
parents:
diff changeset
   760
	// this is called when a process dies.  we want to mark any breakpoints in this
hgs
parents:
diff changeset
   761
	// process space as obsolete.  the main reason for this is so we don't return
hgs
parents:
diff changeset
   762
	// an error when the host debugger tries to clear breakpoints for the process
hgs
parents:
diff changeset
   763
hgs
parents:
diff changeset
   764
	TUint32 codeAddress = 0;
hgs
parents:
diff changeset
   765
	TUint32 codeSize = 0;
hgs
parents:
diff changeset
   766
hgs
parents:
diff changeset
   767
	LOG_EVENT_MSG2("Process being removed, Name %S", aProcess->iName);
hgs
parents:
diff changeset
   768
hgs
parents:
diff changeset
   769
	DCodeSeg* codeSeg = aProcess->iCodeSeg;
hgs
parents:
diff changeset
   770
hgs
parents:
diff changeset
   771
	if (codeSeg)
hgs
parents:
diff changeset
   772
		{
hgs
parents:
diff changeset
   773
		TModuleMemoryInfo processMemoryInfo;
hgs
parents:
diff changeset
   774
		TInt err = codeSeg->GetMemoryInfo(processMemoryInfo, aProcess);
hgs
parents:
diff changeset
   775
		if (err != KErrNone)
hgs
parents:
diff changeset
   776
			{
hgs
parents:
diff changeset
   777
			codeAddress = processMemoryInfo.iCodeBase;
hgs
parents:
diff changeset
   778
			codeSize = processMemoryInfo.iCodeSize;
hgs
parents:
diff changeset
   779
			}
hgs
parents:
diff changeset
   780
		else
hgs
parents:
diff changeset
   781
			{
hgs
parents:
diff changeset
   782
			LOG_MSG2("Error in getting memory info: %d", err);
hgs
parents:
diff changeset
   783
			}
hgs
parents:
diff changeset
   784
		}
hgs
parents:
diff changeset
   785
hgs
parents:
diff changeset
   786
	if (!codeAddress || !codeSize)
hgs
parents:
diff changeset
   787
		{
hgs
parents:
diff changeset
   788
		LOG_EVENT_MSG2("Code segment not available for process %d", aProcess->iId);
hgs
parents:
diff changeset
   789
		// make sure there is not already a breakpoint at this address
hgs
parents:
diff changeset
   790
		for (TInt i = 0; i < iDebugProcessList.Count(); i++)
hgs
parents:
diff changeset
   791
			{
hgs
parents:
diff changeset
   792
			if (iDebugProcessList[i].iId == aProcess->iId)
hgs
parents:
diff changeset
   793
				{
hgs
parents:
diff changeset
   794
				codeAddress = iDebugProcessList[i].iCodeAddress;
hgs
parents:
diff changeset
   795
				codeSize = iDebugProcessList[i].iCodeSize;
hgs
parents:
diff changeset
   796
hgs
parents:
diff changeset
   797
				//now remove from the list
hgs
parents:
diff changeset
   798
				iDebugProcessList.Remove(i);
hgs
parents:
diff changeset
   799
				break;
hgs
parents:
diff changeset
   800
				}
hgs
parents:
diff changeset
   801
			}
hgs
parents:
diff changeset
   802
		}
hgs
parents:
diff changeset
   803
hgs
parents:
diff changeset
   804
	if (!codeAddress || !codeSize)
hgs
parents:
diff changeset
   805
		{
hgs
parents:
diff changeset
   806
		return EFalse;
hgs
parents:
diff changeset
   807
		}
hgs
parents:
diff changeset
   808
hgs
parents:
diff changeset
   809
	iBreakManager->RemoveBreaksForProcess(aProcess->iId, codeAddress, codeSize);
hgs
parents:
diff changeset
   810
	return EFalse;
hgs
parents:
diff changeset
   811
	}
hgs
parents:
diff changeset
   812
hgs
parents:
diff changeset
   813
//
hgs
parents:
diff changeset
   814
// DRM_DebugChannel::StartThread
hgs
parents:
diff changeset
   815
//
hgs
parents:
diff changeset
   816
TBool DRM_DebugChannel::StartThread(TAny* a1, TAny* a2)
hgs
parents:
diff changeset
   817
	{
hgs
parents:
diff changeset
   818
	LOG_EVENT_MSG("DRM_DebugChannel::StartThread()");
hgs
parents:
diff changeset
   819
hgs
parents:
diff changeset
   820
	DThread *aThread = (DThread*)a1;
hgs
parents:
diff changeset
   821
	if(!aThread)
hgs
parents:
diff changeset
   822
		{
hgs
parents:
diff changeset
   823
		LOG_MSG("Error getting DThread object");
hgs
parents:
diff changeset
   824
		__NK_ASSERT_DEBUG(aThread);
hgs
parents:
diff changeset
   825
		return EFalse;
hgs
parents:
diff changeset
   826
		}
hgs
parents:
diff changeset
   827
hgs
parents:
diff changeset
   828
	//a2 points to the thread creating the new thread.
hgs
parents:
diff changeset
   829
	//We have no use for it at the moment so just ignore it for now
hgs
parents:
diff changeset
   830
hgs
parents:
diff changeset
   831
	TDriverEventInfo info;
hgs
parents:
diff changeset
   832
	info.iEventType = EEventsStartThread;
hgs
parents:
diff changeset
   833
	info.iThreadId = aThread->iId;
hgs
parents:
diff changeset
   834
	info.iThreadIdValid = ETrue;
hgs
parents:
diff changeset
   835
	DProcess* owningProcess = aThread->iOwningProcess;
hgs
parents:
diff changeset
   836
	if(owningProcess)
hgs
parents:
diff changeset
   837
		{
hgs
parents:
diff changeset
   838
		info.iProcessId = owningProcess->iId;
hgs
parents:
diff changeset
   839
		info.iProcessIdValid = ETrue;
hgs
parents:
diff changeset
   840
		DCodeSeg* p = owningProcess->iCodeSeg;
hgs
parents:
diff changeset
   841
		if(p && p->iFileName)
hgs
parents:
diff changeset
   842
			{
hgs
parents:
diff changeset
   843
			info.iFileName.Copy(*(p->iFileName));
hgs
parents:
diff changeset
   844
			TheDProcessTracker.NotifyAgentsForProcessEvent(*p->iFileName, info);
hgs
parents:
diff changeset
   845
			}
hgs
parents:
diff changeset
   846
		else
hgs
parents:
diff changeset
   847
			{
hgs
parents:
diff changeset
   848
			if(p)
hgs
parents:
diff changeset
   849
				{
hgs
parents:
diff changeset
   850
				LOG_EVENT_MSG("\tCode segment name missing");
hgs
parents:
diff changeset
   851
				}
hgs
parents:
diff changeset
   852
			else
hgs
parents:
diff changeset
   853
				{
hgs
parents:
diff changeset
   854
				LOG_EVENT_MSG("\tCode segment is NULL");
hgs
parents:
diff changeset
   855
				}
hgs
parents:
diff changeset
   856
			}
hgs
parents:
diff changeset
   857
		}
hgs
parents:
diff changeset
   858
	return EFalse;
hgs
parents:
diff changeset
   859
	}
hgs
parents:
diff changeset
   860
hgs
parents:
diff changeset
   861
//
hgs
parents:
diff changeset
   862
// DRM_DebugChannel::HandleAddProcessEvent
hgs
parents:
diff changeset
   863
//
hgs
parents:
diff changeset
   864
TBool DRM_DebugChannel::HandleAddProcessEvent(TAny* a1, TAny* a2)
hgs
parents:
diff changeset
   865
	{
hgs
parents:
diff changeset
   866
	LOG_EVENT_MSG("DRM_DebugChannel::AddProcess()");
hgs
parents:
diff changeset
   867
hgs
parents:
diff changeset
   868
	DProcess *aProcess = (DProcess*)a1;
hgs
parents:
diff changeset
   869
	// a2 points to the thread creating the new process.
hgs
parents:
diff changeset
   870
	DThread *aThread = (DThread*)a2;
hgs
parents:
diff changeset
   871
hgs
parents:
diff changeset
   872
	if(!aProcess)
hgs
parents:
diff changeset
   873
		{
hgs
parents:
diff changeset
   874
		LOG_MSG("Error getting DProcess object");
hgs
parents:
diff changeset
   875
		__NK_ASSERT_DEBUG(aProcess);
hgs
parents:
diff changeset
   876
		return EFalse;
hgs
parents:
diff changeset
   877
		}
hgs
parents:
diff changeset
   878
hgs
parents:
diff changeset
   879
	TDriverEventInfo info;
hgs
parents:
diff changeset
   880
	info.iEventType = EEventsAddProcess;
hgs
parents:
diff changeset
   881
	info.iProcessId = aProcess->iId;
hgs
parents:
diff changeset
   882
hgs
parents:
diff changeset
   883
	info.iCreatorThreadId  = aThread ? aThread->iId : 0;
hgs
parents:
diff changeset
   884
	info.iProcessIdValid = ETrue;
hgs
parents:
diff changeset
   885
hgs
parents:
diff changeset
   886
	// Copy TUids
hgs
parents:
diff changeset
   887
	info.iUids = aProcess->iUids;
hgs
parents:
diff changeset
   888
hgs
parents:
diff changeset
   889
	info.iUidsValid = ETrue;
hgs
parents:
diff changeset
   890
hgs
parents:
diff changeset
   891
	// copy name of the process
hgs
parents:
diff changeset
   892
	if (aProcess->iName)
hgs
parents:
diff changeset
   893
		{
hgs
parents:
diff changeset
   894
		// copy the name of the process
hgs
parents:
diff changeset
   895
		info.iFileName.Copy(*aProcess->iName);
hgs
parents:
diff changeset
   896
		// AddProcess event does not have fully-qualified path, it has "filename.exe"
hgs
parents:
diff changeset
   897
		// So we allow a less-precise match by passing in ETrue
hgs
parents:
diff changeset
   898
		TheDProcessTracker.NotifyAgentsForProcessEvent(*aProcess->iName, info, ETrue);
hgs
parents:
diff changeset
   899
		}
hgs
parents:
diff changeset
   900
	else
hgs
parents:
diff changeset
   901
		{
hgs
parents:
diff changeset
   902
		LOG_EVENT_MSG("DRM_DebugChannel::AddProcess - No iName for this process");
hgs
parents:
diff changeset
   903
		}
hgs
parents:
diff changeset
   904
hgs
parents:
diff changeset
   905
	return EFalse;
hgs
parents:
diff changeset
   906
	}
hgs
parents:
diff changeset
   907
hgs
parents:
diff changeset
   908
//
hgs
parents:
diff changeset
   909
// DRM_DebugChannel::HandleRemoveProcessEvent
hgs
parents:
diff changeset
   910
//
hgs
parents:
diff changeset
   911
TBool DRM_DebugChannel::HandleRemoveProcessEvent(TAny* a1, TAny* a2)
hgs
parents:
diff changeset
   912
	{
hgs
parents:
diff changeset
   913
	LOG_MSG("DRM_DebugChannel::HandleRemoveProcessEvent()");
hgs
parents:
diff changeset
   914
hgs
parents:
diff changeset
   915
	DProcess *aProcess = (DProcess*)a1;
hgs
parents:
diff changeset
   916
	if(!aProcess)
hgs
parents:
diff changeset
   917
		{
hgs
parents:
diff changeset
   918
		LOG_MSG("Error getting DProcess object");
hgs
parents:
diff changeset
   919
		__NK_ASSERT_DEBUG(aProcess);
hgs
parents:
diff changeset
   920
		return EFalse;
hgs
parents:
diff changeset
   921
		}
hgs
parents:
diff changeset
   922
hgs
parents:
diff changeset
   923
	// a2 points to the thread creating the new process.
hgs
parents:
diff changeset
   924
	// We have no use for it at the moment so just ignore it for now
hgs
parents:
diff changeset
   925
	// Also, it may not be known and therefore NULL
hgs
parents:
diff changeset
   926
hgs
parents:
diff changeset
   927
	TDriverEventInfo info;
hgs
parents:
diff changeset
   928
	info.iEventType = EEventsRemoveProcess;
hgs
parents:
diff changeset
   929
	info.iProcessId = aProcess->iId;
hgs
parents:
diff changeset
   930
	info.iProcessIdValid = ETrue;
hgs
parents:
diff changeset
   931
hgs
parents:
diff changeset
   932
	// copy name of the process
hgs
parents:
diff changeset
   933
	if (aProcess->iName)
hgs
parents:
diff changeset
   934
		{
hgs
parents:
diff changeset
   935
		info.iFileName.Copy(*aProcess->iName);
hgs
parents:
diff changeset
   936
hgs
parents:
diff changeset
   937
		// RemoveProcess event does not have fully-qualified path, it has "filename.exe"
hgs
parents:
diff changeset
   938
		// So we allow a less-precise match by passing in ETrue
hgs
parents:
diff changeset
   939
		TheDProcessTracker.NotifyAgentsForProcessEvent(*aProcess->iName, info, ETrue);
hgs
parents:
diff changeset
   940
		}
hgs
parents:
diff changeset
   941
	else
hgs
parents:
diff changeset
   942
		{
hgs
parents:
diff changeset
   943
		LOG_EVENT_MSG("DRM_DebugChannel::AddProcess - No iName for this process");
hgs
parents:
diff changeset
   944
		}
hgs
parents:
diff changeset
   945
hgs
parents:
diff changeset
   946
	return EFalse;
hgs
parents:
diff changeset
   947
	}
hgs
parents:
diff changeset
   948
hgs
parents:
diff changeset
   949
//
hgs
parents:
diff changeset
   950
// DRM_DebugChannel::AddLibrary
hgs
parents:
diff changeset
   951
//
hgs
parents:
diff changeset
   952
TBool DRM_DebugChannel::AddLibrary(TAny* a1, TAny* a2)
hgs
parents:
diff changeset
   953
	{
hgs
parents:
diff changeset
   954
	LOG_EVENT_MSG("DRM_DebugChannel::AddLibrary()");
hgs
parents:
diff changeset
   955
hgs
parents:
diff changeset
   956
	DLibrary *aLibrary = (DLibrary*)a1;
hgs
parents:
diff changeset
   957
	DThread *aThread = (DThread*)a2;
hgs
parents:
diff changeset
   958
hgs
parents:
diff changeset
   959
	// sanity check
hgs
parents:
diff changeset
   960
	if (!aLibrary)
hgs
parents:
diff changeset
   961
		{
hgs
parents:
diff changeset
   962
		LOG_EVENT_MSG("DRM_DebugChannel::AddLibrary called with no library specified");
hgs
parents:
diff changeset
   963
		return EFalse;
hgs
parents:
diff changeset
   964
		}
hgs
parents:
diff changeset
   965
hgs
parents:
diff changeset
   966
	if (!aThread)
hgs
parents:
diff changeset
   967
		{
hgs
parents:
diff changeset
   968
		LOG_EVENT_MSG("DRM_DebugChannel::AddLibrary called with no thread specified");
hgs
parents:
diff changeset
   969
		return EFalse;
hgs
parents:
diff changeset
   970
		}
hgs
parents:
diff changeset
   971
hgs
parents:
diff changeset
   972
#ifdef __LOG_EVENTS__
hgs
parents:
diff changeset
   973
	TFullName threadName;
hgs
parents:
diff changeset
   974
	aThread->FullName(threadName);
hgs
parents:
diff changeset
   975
	LOG_EVENT_MSG3(("Lib %S loaded by %S"), aLibrary->iName, &threadName);
hgs
parents:
diff changeset
   976
#endif
hgs
parents:
diff changeset
   977
hgs
parents:
diff changeset
   978
	if (aThread)
hgs
parents:
diff changeset
   979
		{
hgs
parents:
diff changeset
   980
		// make sure this is not the debugger thread
hgs
parents:
diff changeset
   981
		if ((aThread != iClientThread) && (aThread->iOwningProcess->iId != iClientThread->iOwningProcess->iId))
hgs
parents:
diff changeset
   982
			{
hgs
parents:
diff changeset
   983
			TDriverEventInfo info;
hgs
parents:
diff changeset
   984
hgs
parents:
diff changeset
   985
			info.iEventType = EEventsAddLibrary;
hgs
parents:
diff changeset
   986
			info.iProcessId = aThread->iOwningProcess->iId;
hgs
parents:
diff changeset
   987
			info.iProcessIdValid = ETrue;
hgs
parents:
diff changeset
   988
			info.iThreadId = aThread->iId;
hgs
parents:
diff changeset
   989
			info.iThreadIdValid = ETrue;
hgs
parents:
diff changeset
   990
hgs
parents:
diff changeset
   991
			//get the code address
hgs
parents:
diff changeset
   992
			DCodeSeg* codeSeg = aLibrary->iCodeSeg;
hgs
parents:
diff changeset
   993
			if (!codeSeg)
hgs
parents:
diff changeset
   994
				{
hgs
parents:
diff changeset
   995
				LOG_EVENT_MSG2("Code segment not available for library %S", aLibrary->iName);
hgs
parents:
diff changeset
   996
				return EFalse;
hgs
parents:
diff changeset
   997
				}
hgs
parents:
diff changeset
   998
hgs
parents:
diff changeset
   999
			// Uid3
hgs
parents:
diff changeset
  1000
			info.iUids = codeSeg->iUids;
hgs
parents:
diff changeset
  1001
			info.iUidsValid = ETrue;
hgs
parents:
diff changeset
  1002
hgs
parents:
diff changeset
  1003
			TModuleMemoryInfo memoryInfo;
hgs
parents:
diff changeset
  1004
			TInt err = codeSeg->GetMemoryInfo(memoryInfo, NULL); //NULL for DProcess should be ok;
hgs
parents:
diff changeset
  1005
			if (err != KErrNone)
hgs
parents:
diff changeset
  1006
				{
hgs
parents:
diff changeset
  1007
				LOG_EVENT_MSG2("Error in getting memory info: %d", err);
hgs
parents:
diff changeset
  1008
				return EFalse;
hgs
parents:
diff changeset
  1009
				}
hgs
parents:
diff changeset
  1010
hgs
parents:
diff changeset
  1011
			info.iCodeAddress = memoryInfo.iCodeBase;
hgs
parents:
diff changeset
  1012
			info.iDataAddress = memoryInfo.iInitialisedDataBase;
hgs
parents:
diff changeset
  1013
hgs
parents:
diff changeset
  1014
			info.iFileName.Copy(*(aLibrary->iName)); //just the name, without uid info.
hgs
parents:
diff changeset
  1015
hgs
parents:
diff changeset
  1016
			//queue up or complete the event
hgs
parents:
diff changeset
  1017
			info.iArg1 = a1;
hgs
parents:
diff changeset
  1018
			info.iArg2 = a2;
hgs
parents:
diff changeset
  1019
			NotifyAgentsFromEventPid(info);
hgs
parents:
diff changeset
  1020
			}
hgs
parents:
diff changeset
  1021
hgs
parents:
diff changeset
  1022
		}
hgs
parents:
diff changeset
  1023
	return EFalse;
hgs
parents:
diff changeset
  1024
	}
hgs
parents:
diff changeset
  1025
hgs
parents:
diff changeset
  1026
//
hgs
parents:
diff changeset
  1027
// DRM_DebugChannel::RemoveLibrary
hgs
parents:
diff changeset
  1028
//
hgs
parents:
diff changeset
  1029
TBool DRM_DebugChannel::RemoveLibrary(TAny* a1, TAny* a2)
hgs
parents:
diff changeset
  1030
	{
hgs
parents:
diff changeset
  1031
	LOG_EVENT_MSG("DRM_DebugChannel::RemoveLibrary()");
hgs
parents:
diff changeset
  1032
	DLibrary *aLibrary = (DLibrary*)a1;
hgs
parents:
diff changeset
  1033
hgs
parents:
diff changeset
  1034
	// sanity check
hgs
parents:
diff changeset
  1035
	if (!aLibrary)
hgs
parents:
diff changeset
  1036
		{
hgs
parents:
diff changeset
  1037
		LOG_EVENT_MSG("DRM_DebugChannel::RemoveLibrary called with no library specified");
hgs
parents:
diff changeset
  1038
		return EFalse;
hgs
parents:
diff changeset
  1039
		}
hgs
parents:
diff changeset
  1040
hgs
parents:
diff changeset
  1041
	LOG_EVENT_MSG2(("Lib unloaded: %S"), aLibrary->iName);
hgs
parents:
diff changeset
  1042
hgs
parents:
diff changeset
  1043
	// this is called when all handles to this library have been closed.  this can happen when a process dies, or when a dll is
hgs
parents:
diff changeset
  1044
	// unloaded while the process lives on.  in former case, we don't need to notify the host debugger because that process is
hgs
parents:
diff changeset
  1045
	// dying anyway.  for the latter case, we do need to notify the host so it can unload the symbolics, etc.
hgs
parents:
diff changeset
  1046
hgs
parents:
diff changeset
  1047
	DThread* aThread = &Kern::CurrentThread();
hgs
parents:
diff changeset
  1048
hgs
parents:
diff changeset
  1049
	if ((aThread) &&
hgs
parents:
diff changeset
  1050
			(aThread != iClientThread) &&
hgs
parents:
diff changeset
  1051
			(aThread->iOwningProcess->iId != iClientThread->iOwningProcess->iId))
hgs
parents:
diff changeset
  1052
		{
hgs
parents:
diff changeset
  1053
		//the library gets unloaded only when the mapcount is 0.
hgs
parents:
diff changeset
  1054
		if (aLibrary->iMapCount != 0)
hgs
parents:
diff changeset
  1055
			return EFalse;
hgs
parents:
diff changeset
  1056
hgs
parents:
diff changeset
  1057
		DCodeSeg* codeSeg = aLibrary->iCodeSeg;
hgs
parents:
diff changeset
  1058
		if (!codeSeg)
hgs
parents:
diff changeset
  1059
			{
hgs
parents:
diff changeset
  1060
			LOG_EVENT_MSG2("Code segment not available for library %S", aLibrary->iName);
hgs
parents:
diff changeset
  1061
			return EFalse;
hgs
parents:
diff changeset
  1062
			}
hgs
parents:
diff changeset
  1063
hgs
parents:
diff changeset
  1064
		TModuleMemoryInfo processMemoryInfo;
hgs
parents:
diff changeset
  1065
		TInt err = codeSeg->GetMemoryInfo(processMemoryInfo, NULL); //passing NULL for the DProcess argument should be ok;
hgs
parents:
diff changeset
  1066
		if (err != KErrNone)
hgs
parents:
diff changeset
  1067
			{
hgs
parents:
diff changeset
  1068
			LOG_EVENT_MSG2("Error in getting memory info: %d", err);
hgs
parents:
diff changeset
  1069
			return EFalse;
hgs
parents:
diff changeset
  1070
			}
hgs
parents:
diff changeset
  1071
hgs
parents:
diff changeset
  1072
		TUint32 codeAddress = processMemoryInfo.iCodeBase;
hgs
parents:
diff changeset
  1073
		TUint32 codeSize = processMemoryInfo.iCodeSize;
hgs
parents:
diff changeset
  1074
hgs
parents:
diff changeset
  1075
		// first invalidate all breakpoints that were set in the library code
hgs
parents:
diff changeset
  1076
		iBreakManager->InvalidateLibraryBreakPoints(codeAddress, codeSize);
hgs
parents:
diff changeset
  1077
		DProcess *process = &Kern::CurrentProcess();
hgs
parents:
diff changeset
  1078
		RArray<SCodeSegEntry>* dynamicCode = &(process->iDynamicCode);
hgs
parents:
diff changeset
  1079
hgs
parents:
diff changeset
  1080
		for (TInt j=0; j<dynamicCode->Count(); j++)
hgs
parents:
diff changeset
  1081
			{
hgs
parents:
diff changeset
  1082
			if ((*dynamicCode)[j].iLib == aLibrary)
hgs
parents:
diff changeset
  1083
				{
hgs
parents:
diff changeset
  1084
				TDriverEventInfo info;
hgs
parents:
diff changeset
  1085
hgs
parents:
diff changeset
  1086
				info.iEventType = EEventsRemoveLibrary;
hgs
parents:
diff changeset
  1087
				info.iFileName.Copy(*(aLibrary->iName)); //lib name without uid info
hgs
parents:
diff changeset
  1088
				//info.iFileName.ZeroTerminate();
hgs
parents:
diff changeset
  1089
				info.iProcessId = process->iId;
hgs
parents:
diff changeset
  1090
				info.iProcessIdValid = ETrue;
hgs
parents:
diff changeset
  1091
				info.iThreadId = 0xFFFFFFFF; // don't care!
hgs
parents:
diff changeset
  1092
				info.iThreadIdValid = EFalse;
hgs
parents:
diff changeset
  1093
				// Uid3
hgs
parents:
diff changeset
  1094
				info.iUids = codeSeg->iUids;
hgs
parents:
diff changeset
  1095
				info.iUidsValid = ETrue;
hgs
parents:
diff changeset
  1096
hgs
parents:
diff changeset
  1097
				//queue up or complete the event
hgs
parents:
diff changeset
  1098
				info.iArg1 = a1;
hgs
parents:
diff changeset
  1099
				info.iArg2 = a2;
hgs
parents:
diff changeset
  1100
				NotifyAgentsFromEventPid(info);
hgs
parents:
diff changeset
  1101
				}
hgs
parents:
diff changeset
  1102
			}
hgs
parents:
diff changeset
  1103
		}
hgs
parents:
diff changeset
  1104
	return EFalse;
hgs
parents:
diff changeset
  1105
	}
hgs
parents:
diff changeset
  1106
hgs
parents:
diff changeset
  1107
//
hgs
parents:
diff changeset
  1108
// DRM_DebugChannel::HandleEventKillThread
hgs
parents:
diff changeset
  1109
//
hgs
parents:
diff changeset
  1110
TBool DRM_DebugChannel::HandleEventKillThread(TAny* a1, TAny* a2)
hgs
parents:
diff changeset
  1111
	{
hgs
parents:
diff changeset
  1112
	DThread* currentThread = &Kern::CurrentThread();
hgs
parents:
diff changeset
  1113
hgs
parents:
diff changeset
  1114
	// a1 should point to the current thread, check this to make sure it does
hgs
parents:
diff changeset
  1115
	__NK_ASSERT_DEBUG((DThread*)a1 == currentThread);
hgs
parents:
diff changeset
  1116
hgs
parents:
diff changeset
  1117
	TDriverEventInfo info;
hgs
parents:
diff changeset
  1118
hgs
parents:
diff changeset
  1119
	LOG_MSG5(" HandleEventKillThread for thread 0x%x, CritScount=%d, suspCnt=%d, waitObj=0x%x", 
hgs
parents:
diff changeset
  1120
			currentThread->iId, 
hgs
parents:
diff changeset
  1121
			currentThread->iNThread.iCsCount, 
hgs
parents:
diff changeset
  1122
			currentThread->iNThread.iSuspendCount,
hgs
parents:
diff changeset
  1123
			currentThread->iWaitObj);
hgs
parents:
diff changeset
  1124
hgs
parents:
diff changeset
  1125
	info.iProcessId = currentThread->iOwningProcess->iId;
hgs
parents:
diff changeset
  1126
	info.iProcessIdValid = ETrue;
hgs
parents:
diff changeset
  1127
	info.iThreadId = currentThread->iId;
hgs
parents:
diff changeset
  1128
	info.iThreadIdValid = ETrue;
hgs
parents:
diff changeset
  1129
	
hgs
parents:
diff changeset
  1130
	TInt err = ReadKernelRegisterValue(currentThread, 14, info.iCurrentPC);
hgs
parents:
diff changeset
  1131
	if(err != KErrNone)
hgs
parents:
diff changeset
  1132
		{
hgs
parents:
diff changeset
  1133
		LOG_EVENT_MSG2("DRM_DebugChannel::HandleEventKillThread - Non-zero error code discarded: %d", err);
hgs
parents:
diff changeset
  1134
		}
hgs
parents:
diff changeset
  1135
hgs
parents:
diff changeset
  1136
	LOG_MSG5(" HandleEventKillThread for thread exit category=%S reason=%d, exitType=0x%x, PC=0x%x",
hgs
parents:
diff changeset
  1137
			&currentThread->iExitCategory,
hgs
parents:
diff changeset
  1138
	 	 	 currentThread->iExitReason, 
hgs
parents:
diff changeset
  1139
	 		 currentThread->iExitType,
hgs
parents:
diff changeset
  1140
			 info.iCurrentPC);
hgs
parents:
diff changeset
  1141
			
hgs
parents:
diff changeset
  1142
	if (currentThread->iExitType == EExitPanic)
hgs
parents:
diff changeset
  1143
		{
hgs
parents:
diff changeset
  1144
		info.iPanicCategory.Copy(currentThread->iExitCategory);
hgs
parents:
diff changeset
  1145
		}
hgs
parents:
diff changeset
  1146
	info.iExceptionNumber = currentThread->iExitReason;
hgs
parents:
diff changeset
  1147
	info.iExitType = currentThread->iExitType;
hgs
parents:
diff changeset
  1148
	info.iEventType = EEventsKillThread;
hgs
parents:
diff changeset
  1149
	info.iThreadFlags = currentThread->iFlags;
hgs
parents:
diff changeset
  1150
hgs
parents:
diff changeset
  1151
	// remove all the breakpoints in this thread, whether we are debugging it or not.
hgs
parents:
diff changeset
  1152
	iBreakManager->DoRemoveThreadBreaks(info.iThreadId);
hgs
parents:
diff changeset
  1153
hgs
parents:
diff changeset
  1154
	info.iArg1 = a1;
hgs
parents:
diff changeset
  1155
	info.iArg2 = a2;
hgs
parents:
diff changeset
  1156
	NotifyAgentsFromEventPid(info);
hgs
parents:
diff changeset
  1157
hgs
parents:
diff changeset
  1158
	return ETrue;
hgs
parents:
diff changeset
  1159
	}
hgs
parents:
diff changeset
  1160
hgs
parents:
diff changeset
  1161
//
hgs
parents:
diff changeset
  1162
// DRM_DebugChannel::HandleSwException
hgs
parents:
diff changeset
  1163
//
hgs
parents:
diff changeset
  1164
TBool DRM_DebugChannel::HandleSwException(TAny* a1, TAny* a2)
hgs
parents:
diff changeset
  1165
	{
hgs
parents:
diff changeset
  1166
	LOG_EVENT_MSG("DRM_DebugChannel::HandleSwException");
hgs
parents:
diff changeset
  1167
	TExcType aExcType = (TExcType)(TInt)a1;
hgs
parents:
diff changeset
  1168
hgs
parents:
diff changeset
  1169
	TDriverEventInfo info;
hgs
parents:
diff changeset
  1170
hgs
parents:
diff changeset
  1171
	DThread* currentThread = &Kern::CurrentThread();
hgs
parents:
diff changeset
  1172
	if (!currentThread)
hgs
parents:
diff changeset
  1173
		{
hgs
parents:
diff changeset
  1174
		LOG_MSG("Error getting current thread");
hgs
parents:
diff changeset
  1175
		__NK_ASSERT_DEBUG(currentThread);
hgs
parents:
diff changeset
  1176
		return EFalse;
hgs
parents:
diff changeset
  1177
		}
hgs
parents:
diff changeset
  1178
hgs
parents:
diff changeset
  1179
	info.iProcessId = currentThread->iOwningProcess->iId;
hgs
parents:
diff changeset
  1180
	info.iProcessIdValid = ETrue;
hgs
parents:
diff changeset
  1181
	info.iThreadId = currentThread->iId;
hgs
parents:
diff changeset
  1182
	info.iThreadIdValid = ETrue;
hgs
parents:
diff changeset
  1183
	TInt err = ReadKernelRegisterValue(currentThread, PC_REGISTER, info.iCurrentPC);
hgs
parents:
diff changeset
  1184
	if(err != KErrNone)
hgs
parents:
diff changeset
  1185
		{
hgs
parents:
diff changeset
  1186
		LOG_EVENT_MSG2("DRM_DebugChannel::HandleSwException - Non-zero error code discarded: %d", err);
hgs
parents:
diff changeset
  1187
		}
hgs
parents:
diff changeset
  1188
	info.iExceptionNumber = aExcType;
hgs
parents:
diff changeset
  1189
	info.iEventType = EEventsSwExc;
hgs
parents:
diff changeset
  1190
	info.iThreadFlags = currentThread->iFlags;
hgs
parents:
diff changeset
  1191
	info.iArg1 = a1;
hgs
parents:
diff changeset
  1192
	info.iArg2 = a2;
hgs
parents:
diff changeset
  1193
hgs
parents:
diff changeset
  1194
	NotifyAgentsFromEventPid(info);
hgs
parents:
diff changeset
  1195
hgs
parents:
diff changeset
  1196
	return EFalse;
hgs
parents:
diff changeset
  1197
	}
hgs
parents:
diff changeset
  1198
hgs
parents:
diff changeset
  1199
//
hgs
parents:
diff changeset
  1200
// DRM_DebugChannel::HandleHwException
hgs
parents:
diff changeset
  1201
//
hgs
parents:
diff changeset
  1202
TBool DRM_DebugChannel::HandleHwException(TAny* a1, TAny* a2)
hgs
parents:
diff changeset
  1203
	{
hgs
parents:
diff changeset
  1204
	TArmExcInfo* aExcInfo = (TArmExcInfo*)a1;
hgs
parents:
diff changeset
  1205
hgs
parents:
diff changeset
  1206
	// sanity check
hgs
parents:
diff changeset
  1207
	if (!aExcInfo)
hgs
parents:
diff changeset
  1208
		{
hgs
parents:
diff changeset
  1209
		LOG_MSG("DRM_DebugChannel::HandleHwException called with no aExcInfo");
hgs
parents:
diff changeset
  1210
		__NK_ASSERT_DEBUG(aExcInfo);
hgs
parents:
diff changeset
  1211
		return EFalse;
hgs
parents:
diff changeset
  1212
		}
hgs
parents:
diff changeset
  1213
hgs
parents:
diff changeset
  1214
	TDriverEventInfo info;
hgs
parents:
diff changeset
  1215
hgs
parents:
diff changeset
  1216
	DThread* currentThread = &Kern::CurrentThread();
hgs
parents:
diff changeset
  1217
hgs
parents:
diff changeset
  1218
	if (!currentThread)
hgs
parents:
diff changeset
  1219
		{
hgs
parents:
diff changeset
  1220
		LOG_MSG("Error getting current thread");
hgs
parents:
diff changeset
  1221
		__NK_ASSERT_DEBUG(currentThread);
hgs
parents:
diff changeset
  1222
		return EFalse;
hgs
parents:
diff changeset
  1223
		}
hgs
parents:
diff changeset
  1224
hgs
parents:
diff changeset
  1225
	info.iProcessId = currentThread->iOwningProcess->iId;
hgs
parents:
diff changeset
  1226
	info.iProcessIdValid = ETrue;
hgs
parents:
diff changeset
  1227
	info.iThreadId = currentThread->iId;
hgs
parents:
diff changeset
  1228
	info.iThreadIdValid = ETrue;
hgs
parents:
diff changeset
  1229
	info.iRmdArmExcInfo.iFaultAddress= aExcInfo->iFaultAddress;
hgs
parents:
diff changeset
  1230
	info.iRmdArmExcInfo.iFaultStatus= aExcInfo->iFaultStatus;
hgs
parents:
diff changeset
  1231
hgs
parents:
diff changeset
  1232
	LOG_MSG5("DRM_DebugChannel::HandleHwException current thread = 0x%08x, CritSect count=%d,\n"
hgs
parents:
diff changeset
  1233
		" iFaultAddress=0x%08x, iFaultStatus=0x%08x",
hgs
parents:
diff changeset
  1234
		currentThread, currentThread->iNThread.iCsCount, aExcInfo->iFaultAddress, aExcInfo->iFaultStatus);
hgs
parents:
diff changeset
  1235
hgs
parents:
diff changeset
  1236
hgs
parents:
diff changeset
  1237
	LOG_MSG3(" HandleHwException CsFunc=%d, suspCount=%d",
hgs
parents:
diff changeset
  1238
			currentThread->iNThread.iCsFunction, currentThread->iNThread.iSuspendCount );  
hgs
parents:
diff changeset
  1239
		
hgs
parents:
diff changeset
  1240
	info.iRmdArmExcInfo.iR0= aExcInfo->iR0;
hgs
parents:
diff changeset
  1241
	info.iRmdArmExcInfo.iR1= aExcInfo->iR1;
hgs
parents:
diff changeset
  1242
	info.iRmdArmExcInfo.iR2= aExcInfo->iR2;
hgs
parents:
diff changeset
  1243
	info.iRmdArmExcInfo.iR3= aExcInfo->iR3;
hgs
parents:
diff changeset
  1244
hgs
parents:
diff changeset
  1245
	info.iRmdArmExcInfo.iR4= aExcInfo->iR4;
hgs
parents:
diff changeset
  1246
	info.iRmdArmExcInfo.iR5= aExcInfo->iR5;
hgs
parents:
diff changeset
  1247
	info.iRmdArmExcInfo.iR6= aExcInfo->iR6;
hgs
parents:
diff changeset
  1248
	info.iRmdArmExcInfo.iR7= aExcInfo->iR7;
hgs
parents:
diff changeset
  1249
	info.iRmdArmExcInfo.iR8= aExcInfo->iR8;
hgs
parents:
diff changeset
  1250
	info.iRmdArmExcInfo.iR9= aExcInfo->iR9;
hgs
parents:
diff changeset
  1251
	info.iRmdArmExcInfo.iR10= aExcInfo->iR10;
hgs
parents:
diff changeset
  1252
	info.iRmdArmExcInfo.iR11= aExcInfo->iR11;
hgs
parents:
diff changeset
  1253
	info.iRmdArmExcInfo.iR12= aExcInfo->iR12;
hgs
parents:
diff changeset
  1254
hgs
parents:
diff changeset
  1255
	info.iRmdArmExcInfo.iR13= aExcInfo->iR13;
hgs
parents:
diff changeset
  1256
	info.iRmdArmExcInfo.iR14= aExcInfo->iR14;
hgs
parents:
diff changeset
  1257
	info.iRmdArmExcInfo.iR15= aExcInfo->iR15;
hgs
parents:
diff changeset
  1258
hgs
parents:
diff changeset
  1259
	info.iRmdArmExcInfo.iCpsr= aExcInfo->iCpsr;
hgs
parents:
diff changeset
  1260
	info.iRmdArmExcInfo.iR13Svc= aExcInfo->iR13Svc;
hgs
parents:
diff changeset
  1261
	info.iRmdArmExcInfo.iR14Svc= aExcInfo->iR14Svc;
hgs
parents:
diff changeset
  1262
	info.iRmdArmExcInfo.iSpsrSvc= aExcInfo->iSpsrSvc;
hgs
parents:
diff changeset
  1263
	LOG_MSG5(" iCpsr=0x%x, iExcCode=0x%x, R14=0x%x, R15=0x%x",
hgs
parents:
diff changeset
  1264
			aExcInfo->iCpsr, aExcInfo->iExcCode, aExcInfo->iR14, aExcInfo->iR15);
hgs
parents:
diff changeset
  1265
hgs
parents:
diff changeset
  1266
	switch (aExcInfo->iExcCode)
hgs
parents:
diff changeset
  1267
		{
hgs
parents:
diff changeset
  1268
		case 0:
hgs
parents:
diff changeset
  1269
			info.iExceptionNumber = EExcCodeAbort;
hgs
parents:
diff changeset
  1270
			LOG_MSG(" iExcCode == 0 => EExcCodeAbort");
hgs
parents:
diff changeset
  1271
			break;
hgs
parents:
diff changeset
  1272
		case 1:
hgs
parents:
diff changeset
  1273
			info.iExceptionNumber = EExcDataAbort;
hgs
parents:
diff changeset
  1274
			LOG_MSG(" iExcCode == 1 => EExcDataAbort");
hgs
parents:
diff changeset
  1275
			break;
hgs
parents:
diff changeset
  1276
		case 2:
hgs
parents:
diff changeset
  1277
			info.iExceptionNumber = EExcInvalidOpCode;
hgs
parents:
diff changeset
  1278
			LOG_MSG(" iExcCode == 2 => EExcInvalidOpCode");
hgs
parents:
diff changeset
  1279
			break;
hgs
parents:
diff changeset
  1280
		default:
hgs
parents:
diff changeset
  1281
			// new event? Something gone wrong?
hgs
parents:
diff changeset
  1282
			__NK_ASSERT_DEBUG(EFalse);
hgs
parents:
diff changeset
  1283
			return EFalse;
hgs
parents:
diff changeset
  1284
		}
hgs
parents:
diff changeset
  1285
hgs
parents:
diff changeset
  1286
	info.iEventType = EEventsHwExc;
hgs
parents:
diff changeset
  1287
	info.iThreadFlags = currentThread->iFlags;
hgs
parents:
diff changeset
  1288
hgs
parents:
diff changeset
  1289
	info.iArg1 = a1;
hgs
parents:
diff changeset
  1290
	info.iArg2 = a2;
hgs
parents:
diff changeset
  1291
hgs
parents:
diff changeset
  1292
	if(EExcInvalidOpCode == info.iExceptionNumber)
hgs
parents:
diff changeset
  1293
		{
hgs
parents:
diff changeset
  1294
		return HandleInvalidOpCodeException(info, currentThread);
hgs
parents:
diff changeset
  1295
		}
hgs
parents:
diff changeset
  1296
hgs
parents:
diff changeset
  1297
	NotifyAgentsFromEventPid(info);
hgs
parents:
diff changeset
  1298
	return EFalse;
hgs
parents:
diff changeset
  1299
	}
hgs
parents:
diff changeset
  1300
hgs
parents:
diff changeset
  1301
//
hgs
parents:
diff changeset
  1302
// DRM_DebugChannel::HandUserTrace
hgs
parents:
diff changeset
  1303
//
hgs
parents:
diff changeset
  1304
TBool DRM_DebugChannel::HandleUserTrace(TAny* a1, TAny* a2)
hgs
parents:
diff changeset
  1305
	{
hgs
parents:
diff changeset
  1306
	LOG_EVENT_MSG("DRM_DebugChannel::HandleUserTrace()");
hgs
parents:
diff changeset
  1307
hgs
parents:
diff changeset
  1308
	DThread* currentThread = &Kern::CurrentThread();
hgs
parents:
diff changeset
  1309
	if (!currentThread)
hgs
parents:
diff changeset
  1310
		{
hgs
parents:
diff changeset
  1311
		LOG_EVENT_MSG("Error getting current thread");
hgs
parents:
diff changeset
  1312
		__NK_ASSERT_DEBUG(currentThread);
hgs
parents:
diff changeset
  1313
		return EFalse;
hgs
parents:
diff changeset
  1314
		}
hgs
parents:
diff changeset
  1315
hgs
parents:
diff changeset
  1316
	TDriverEventInfo info;
hgs
parents:
diff changeset
  1317
	info.iProcessId = currentThread->iOwningProcess->iId;
hgs
parents:
diff changeset
  1318
	info.iProcessIdValid = ETrue;
hgs
parents:
diff changeset
  1319
	info.iThreadId = currentThread->iId;
hgs
parents:
diff changeset
  1320
	info.iThreadIdValid = ETrue;
hgs
parents:
diff changeset
  1321
	info.iEventType = EEventsUserTrace;
hgs
parents:
diff changeset
  1322
	info.iArg1 = a1;
hgs
parents:
diff changeset
  1323
	info.iArg2 = a2;
hgs
parents:
diff changeset
  1324
hgs
parents:
diff changeset
  1325
	TInt err = KErrNone;
hgs
parents:
diff changeset
  1326
hgs
parents:
diff changeset
  1327
	//User Trace info
hgs
parents:
diff changeset
  1328
	XTRAP(err, XT_DEFAULT, kumemget(info.iUserTraceText, info.iArg1, (TInt)a2));
hgs
parents:
diff changeset
  1329
	if(KErrNone != err)
hgs
parents:
diff changeset
  1330
		{
hgs
parents:
diff changeset
  1331
		return EFalse;
hgs
parents:
diff changeset
  1332
		}
hgs
parents:
diff changeset
  1333
hgs
parents:
diff changeset
  1334
	info.iMessageStatus = ESingleMessage;
hgs
parents:
diff changeset
  1335
hgs
parents:
diff changeset
  1336
	NotifyAgentsFromEventPid(info);
hgs
parents:
diff changeset
  1337
hgs
parents:
diff changeset
  1338
	return EFalse;
hgs
parents:
diff changeset
  1339
	}
hgs
parents:
diff changeset
  1340
hgs
parents:
diff changeset
  1341
//
hgs
parents:
diff changeset
  1342
// DRM_DebugChannel::HandleException
hgs
parents:
diff changeset
  1343
//
hgs
parents:
diff changeset
  1344
TBool DRM_DebugChannel::HandleInvalidOpCodeException(TDriverEventInfo& aEventInfo, DThread* aCurrentThread)
hgs
parents:
diff changeset
  1345
	{
hgs
parents:
diff changeset
  1346
	LOG_MSG("DRM_DebugChannel::HandleInvalidOpCodeException()");
hgs
parents:
diff changeset
  1347
hgs
parents:
diff changeset
  1348
	TInt err = KErrNone;
hgs
parents:
diff changeset
  1349
hgs
parents:
diff changeset
  1350
	TUint32 inst = KArmBreakPoint;
hgs
parents:
diff changeset
  1351
	TInt instSize = 4;
hgs
parents:
diff changeset
  1352
hgs
parents:
diff changeset
  1353
	// change these for thumb mode
hgs
parents:
diff changeset
  1354
	TUint32 regValue;
hgs
parents:
diff changeset
  1355
	err = ReadKernelRegisterValue(aCurrentThread, STATUS_REGISTER, regValue);
hgs
parents:
diff changeset
  1356
	if(err != KErrNone)
hgs
parents:
diff changeset
  1357
		{
hgs
parents:
diff changeset
  1358
		LOG_MSG2("DRM_DebugChannel::HandleInvalidOpCodeException - Non-zero error code discarded: %d", err);
hgs
parents:
diff changeset
  1359
		}
hgs
parents:
diff changeset
  1360
hgs
parents:
diff changeset
  1361
	if (regValue & ECpuThumb)
hgs
parents:
diff changeset
  1362
		{
hgs
parents:
diff changeset
  1363
		inst = KThumbBreakPoint;
hgs
parents:
diff changeset
  1364
		instSize = 2;
hgs
parents:
diff changeset
  1365
		}
hgs
parents:
diff changeset
  1366
hgs
parents:
diff changeset
  1367
	TUint32 instruction = 0;
hgs
parents:
diff changeset
  1368
	err = Kern::ThreadRawRead(aCurrentThread, (TUint32 *)aEventInfo.iRmdArmExcInfo.iR15, (TUint8 *)&instruction, instSize);
hgs
parents:
diff changeset
  1369
hgs
parents:
diff changeset
  1370
	if (KErrNone != err)
hgs
parents:
diff changeset
  1371
		LOG_MSG2("Error reading instruction at currentpc: %d", err);
hgs
parents:
diff changeset
  1372
hgs
parents:
diff changeset
  1373
	if (!memcompare((TUint8 *)&inst, instSize, (TUint8 *)&instruction, instSize))
hgs
parents:
diff changeset
  1374
		{
hgs
parents:
diff changeset
  1375
		TInt err = DoSuspendThread(aCurrentThread);
hgs
parents:
diff changeset
  1376
		if(! ((KErrNone == err) || (KErrAlreadyExists == err)) )
hgs
parents:
diff changeset
  1377
			{
hgs
parents:
diff changeset
  1378
			LOG_MSG2("DRM_DebugChannel::HandleInvalidOpCodeException() Thread with id 0x%08x could not be suspended.", aCurrentThread->iId);
hgs
parents:
diff changeset
  1379
			return EFalse;
hgs
parents:
diff changeset
  1380
			}
hgs
parents:
diff changeset
  1381
hgs
parents:
diff changeset
  1382
		// the exception was a breakpoint instruction.  see if we have a breakpoint at that address
hgs
parents:
diff changeset
  1383
		TBreakEntry* breakEntry = NULL;
hgs
parents:
diff changeset
  1384
		do
hgs
parents:
diff changeset
  1385
			{
hgs
parents:
diff changeset
  1386
			breakEntry = iBreakManager->GetNextBreak(breakEntry);
hgs
parents:
diff changeset
  1387
			if (breakEntry && ((breakEntry->iThreadSpecific && breakEntry->iId == aEventInfo.iThreadId) || (!breakEntry->iThreadSpecific && breakEntry->iId == aEventInfo.iProcessId)) && breakEntry->iAddress == aEventInfo.iRmdArmExcInfo.iR15)
hgs
parents:
diff changeset
  1388
				{
hgs
parents:
diff changeset
  1389
				LOG_MSG2("Breakpoint with Id %d has been hit", breakEntry->iBreakId);
hgs
parents:
diff changeset
  1390
hgs
parents:
diff changeset
  1391
				TBreakEntry tempBreakEntry = *breakEntry;
hgs
parents:
diff changeset
  1392
hgs
parents:
diff changeset
  1393
				//change the event type to breakpoint type
hgs
parents:
diff changeset
  1394
				aEventInfo.iEventType = breakEntry->iThreadSpecific ? EEventsBreakPoint : EEventsProcessBreakPoint;
hgs
parents:
diff changeset
  1395
hgs
parents:
diff changeset
  1396
				// enable any breakpoints we had to disable for this thread
hgs
parents:
diff changeset
  1397
				err = iBreakManager->DoEnableDisabledBreak(aEventInfo.iThreadId);
hgs
parents:
diff changeset
  1398
				if (KErrNone != err)
hgs
parents:
diff changeset
  1399
					LOG_MSG2("Error %d enabling disabled breakpoints", err);
hgs
parents:
diff changeset
  1400
hgs
parents:
diff changeset
  1401
				// see if this is a temp breakpoint
hgs
parents:
diff changeset
  1402
				if (iBreakManager->IsTemporaryBreak(*breakEntry))
hgs
parents:
diff changeset
  1403
					{
hgs
parents:
diff changeset
  1404
					// this was a temp breakpoint, so we need to clear it now
hgs
parents:
diff changeset
  1405
					err = iBreakManager->DoClearBreak(breakEntry->iBreakId);
hgs
parents:
diff changeset
  1406
					if (KErrNone != err)
hgs
parents:
diff changeset
  1407
						LOG_MSG2("Error %d clearing temp breakpoint", err);
hgs
parents:
diff changeset
  1408
hgs
parents:
diff changeset
  1409
					// Find out how many steps remain to be done
hgs
parents:
diff changeset
  1410
hgs
parents:
diff changeset
  1411
					// reduce the number of steps to complete by 1
hgs
parents:
diff changeset
  1412
					tempBreakEntry.iNumSteps--;
hgs
parents:
diff changeset
  1413
hgs
parents:
diff changeset
  1414
					LOG_MSG2("There are %d steps remaining\n", tempBreakEntry.iNumSteps);
hgs
parents:
diff changeset
  1415
hgs
parents:
diff changeset
  1416
					// New. If we have not finished do all the steps, continue stepping and don't notify event
hgs
parents:
diff changeset
  1417
					if (tempBreakEntry.iNumSteps)
hgs
parents:
diff changeset
  1418
						{
hgs
parents:
diff changeset
  1419
						LOG_MSG("Continuing stepping...not telling the agent yet\n");
hgs
parents:
diff changeset
  1420
						err = DoStepRange(aCurrentThread, aEventInfo.iRmdArmExcInfo.iR15, aEventInfo.iRmdArmExcInfo.iR15, ETrue, tempBreakEntry.iResumeOnceOutOfRange /*EFalse*/, tempBreakEntry.iNumSteps, ETrue);
hgs
parents:
diff changeset
  1421
						if (err != KErrNone)
hgs
parents:
diff changeset
  1422
							{
hgs
parents:
diff changeset
  1423
							LOG_EVENT_MSG("Failed to continue stepping\n");
hgs
parents:
diff changeset
  1424
hgs
parents:
diff changeset
  1425
							// what do we do? might as well stop here and tell the user
hgs
parents:
diff changeset
  1426
							NotifyAgentsFromEventPid(aEventInfo);
hgs
parents:
diff changeset
  1427
hgs
parents:
diff changeset
  1428
							return ETrue;
hgs
parents:
diff changeset
  1429
							}
hgs
parents:
diff changeset
  1430
hgs
parents:
diff changeset
  1431
						// continue as though no event occured. No need to suspend/resume anything...
hgs
parents:
diff changeset
  1432
						LOG_MSG("Continuing to step\n");
hgs
parents:
diff changeset
  1433
						return ETrue;
hgs
parents:
diff changeset
  1434
						}
hgs
parents:
diff changeset
  1435
hgs
parents:
diff changeset
  1436
					// Is this a case where we just want to continue?
hgs
parents:
diff changeset
  1437
					if (tempBreakEntry.iResumeOnceOutOfRange)
hgs
parents:
diff changeset
  1438
						{
hgs
parents:
diff changeset
  1439
						LOG_MSG("PC is out of range, continuing thread");
hgs
parents:
diff changeset
  1440
						DoResumeThread(aCurrentThread);
hgs
parents:
diff changeset
  1441
hgs
parents:
diff changeset
  1442
						return ETrue;
hgs
parents:
diff changeset
  1443
						}
hgs
parents:
diff changeset
  1444
					}
hgs
parents:
diff changeset
  1445
hgs
parents:
diff changeset
  1446
				// if the breakpoint is thread specific, make sure it's the right thread
hgs
parents:
diff changeset
  1447
				// if not, just continue the thread.  take special care if it's the debugger
hgs
parents:
diff changeset
  1448
				// thread.  if it hits a regular breakpoint, we NEVER want to stop at it.  if
hgs
parents:
diff changeset
  1449
				// it hits a temp breakpoint, we're probably just stepping past a real breakpoint
hgs
parents:
diff changeset
  1450
				// and we do need to handle it.
hgs
parents:
diff changeset
  1451
				TBool needToResume = (tempBreakEntry.iThreadSpecific && tempBreakEntry.iId != aEventInfo.iThreadId) ||
hgs
parents:
diff changeset
  1452
					(!tempBreakEntry.iThreadSpecific && tempBreakEntry.iId != aEventInfo.iProcessId);
hgs
parents:
diff changeset
  1453
hgs
parents:
diff changeset
  1454
				if (needToResume)
hgs
parents:
diff changeset
  1455
					{
hgs
parents:
diff changeset
  1456
					LOG_MSG("breakpoint does not match threadId, calling DoResumeThread");
hgs
parents:
diff changeset
  1457
					err = DoResumeThread(aCurrentThread);
hgs
parents:
diff changeset
  1458
					if (KErrNone != err)
hgs
parents:
diff changeset
  1459
						LOG_MSG2("Error in DoResumeThread: %d", err);
hgs
parents:
diff changeset
  1460
hgs
parents:
diff changeset
  1461
					return EFalse;
hgs
parents:
diff changeset
  1462
					}
hgs
parents:
diff changeset
  1463
hgs
parents:
diff changeset
  1464
				//normal user break point, just notify the event
hgs
parents:
diff changeset
  1465
				break;
hgs
parents:
diff changeset
  1466
				}
hgs
parents:
diff changeset
  1467
			} while(breakEntry);
hgs
parents:
diff changeset
  1468
		}
hgs
parents:
diff changeset
  1469
hgs
parents:
diff changeset
  1470
	NotifyAgentsFromEventPid(aEventInfo);
hgs
parents:
diff changeset
  1471
hgs
parents:
diff changeset
  1472
	return (aEventInfo.iEventType == EEventsBreakPoint) || (aEventInfo.iEventType == EEventsProcessBreakPoint);
hgs
parents:
diff changeset
  1473
	}
hgs
parents:
diff changeset
  1474
hgs
parents:
diff changeset
  1475
//
hgs
parents:
diff changeset
  1476
// DRM_DebugChannel::SetBreak
hgs
parents:
diff changeset
  1477
//
hgs
parents:
diff changeset
  1478
TInt DRM_DebugChannel::SetBreak(TSetBreakInfo* aBreakInfo)
hgs
parents:
diff changeset
  1479
	{
hgs
parents:
diff changeset
  1480
	LOG_MSG("DRM_DebugChannel::SetBreak()");
hgs
parents:
diff changeset
  1481
hgs
parents:
diff changeset
  1482
	TInt err = KErrNone;
hgs
parents:
diff changeset
  1483
hgs
parents:
diff changeset
  1484
	if (!aBreakInfo)
hgs
parents:
diff changeset
  1485
		{
hgs
parents:
diff changeset
  1486
		LOG_MSG("DRM_DebugChannel::SetBreak() was passed a NULL argument");
hgs
parents:
diff changeset
  1487
		return KErrArgument;
hgs
parents:
diff changeset
  1488
		}
hgs
parents:
diff changeset
  1489
hgs
parents:
diff changeset
  1490
	//User side memory is not accessible directly
hgs
parents:
diff changeset
  1491
	TSetBreakInfo info;
hgs
parents:
diff changeset
  1492
	err = Kern::ThreadRawRead(iClientThread, aBreakInfo, (TUint8*)&info, sizeof(TSetBreakInfo));
hgs
parents:
diff changeset
  1493
	if (err != KErrNone)
hgs
parents:
diff changeset
  1494
		{
hgs
parents:
diff changeset
  1495
		LOG_MSG("DRM_DebugChannel::SetBreak() was passed a bad argument");
hgs
parents:
diff changeset
  1496
		return err;
hgs
parents:
diff changeset
  1497
		}
hgs
parents:
diff changeset
  1498
hgs
parents:
diff changeset
  1499
	DProcess* process = NULL;
hgs
parents:
diff changeset
  1500
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  1501
	if(info.iThreadSpecific)
hgs
parents:
diff changeset
  1502
		{
hgs
parents:
diff changeset
  1503
		DThread* thread = DebugUtils::OpenThreadHandle(info.iId);
hgs
parents:
diff changeset
  1504
		if(!thread)
hgs
parents:
diff changeset
  1505
			{
hgs
parents:
diff changeset
  1506
			LOG_MSG2("DRM_DebugChannel::SetBreak() Thread with id 0x%08x not found", info.iId);
hgs
parents:
diff changeset
  1507
			}
hgs
parents:
diff changeset
  1508
		else
hgs
parents:
diff changeset
  1509
			{
hgs
parents:
diff changeset
  1510
			process = DebugUtils::OpenProcessHandle(thread->iOwningProcess->iId);
hgs
parents:
diff changeset
  1511
			thread->Close(NULL);
hgs
parents:
diff changeset
  1512
			}
hgs
parents:
diff changeset
  1513
		}
hgs
parents:
diff changeset
  1514
	else
hgs
parents:
diff changeset
  1515
		{
hgs
parents:
diff changeset
  1516
		process = DebugUtils::OpenProcessHandle(info.iId);
hgs
parents:
diff changeset
  1517
		if(!process)
hgs
parents:
diff changeset
  1518
			{
hgs
parents:
diff changeset
  1519
			LOG_MSG2("DRM_DebugChannel::SetBreak() Process with id 0x%08x not found", info.iId);
hgs
parents:
diff changeset
  1520
			}
hgs
parents:
diff changeset
  1521
		}
hgs
parents:
diff changeset
  1522
hgs
parents:
diff changeset
  1523
	if (process == NULL)
hgs
parents:
diff changeset
  1524
		{
hgs
parents:
diff changeset
  1525
		NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  1526
		return KErrNotFound;
hgs
parents:
diff changeset
  1527
		}
hgs
parents:
diff changeset
  1528
hgs
parents:
diff changeset
  1529
	TBool found = EFalse;
hgs
parents:
diff changeset
  1530
	for(TInt i=0; i<iDebugProcessList.Count(); i++)
hgs
parents:
diff changeset
  1531
		{
hgs
parents:
diff changeset
  1532
		if(process->iId == iDebugProcessList[i].iId)
hgs
parents:
diff changeset
  1533
			{
hgs
parents:
diff changeset
  1534
			found = ETrue;
hgs
parents:
diff changeset
  1535
			}
hgs
parents:
diff changeset
  1536
		}
hgs
parents:
diff changeset
  1537
hgs
parents:
diff changeset
  1538
	if(!found)
hgs
parents:
diff changeset
  1539
		{
hgs
parents:
diff changeset
  1540
		DCodeSeg* codeSeg = process->iCodeSeg;
hgs
parents:
diff changeset
  1541
		if (!codeSeg)
hgs
parents:
diff changeset
  1542
			{
hgs
parents:
diff changeset
  1543
			LOG_MSG2("DRM_DebugChannel::SetBreak() Code seg for process with id 0x%08x not found", process->iId);
hgs
parents:
diff changeset
  1544
			err = KErrNotFound;
hgs
parents:
diff changeset
  1545
			}
hgs
parents:
diff changeset
  1546
hgs
parents:
diff changeset
  1547
		TModuleMemoryInfo memoryInfo;
hgs
parents:
diff changeset
  1548
		if (!err)
hgs
parents:
diff changeset
  1549
			{
hgs
parents:
diff changeset
  1550
			err = codeSeg->GetMemoryInfo(memoryInfo, process);
hgs
parents:
diff changeset
  1551
			if (err != KErrNone)
hgs
parents:
diff changeset
  1552
				{
hgs
parents:
diff changeset
  1553
				LOG_MSG2("DRM_DebugChannel::SetBreak() Error getting memory info for process with id 0x%08x", process->iId);
hgs
parents:
diff changeset
  1554
				}
hgs
parents:
diff changeset
  1555
			}
hgs
parents:
diff changeset
  1556
hgs
parents:
diff changeset
  1557
		if (!err)
hgs
parents:
diff changeset
  1558
			{
hgs
parents:
diff changeset
  1559
			//add this process to the list of processes that we are debugging
hgs
parents:
diff changeset
  1560
			TProcessInfo processInfo(process->iId, memoryInfo.iCodeBase, memoryInfo.iCodeSize, memoryInfo.iInitialisedDataBase);
hgs
parents:
diff changeset
  1561
			iDebugProcessList.Append(processInfo);
hgs
parents:
diff changeset
  1562
			}
hgs
parents:
diff changeset
  1563
		}
hgs
parents:
diff changeset
  1564
hgs
parents:
diff changeset
  1565
	process->Close(NULL);
hgs
parents:
diff changeset
  1566
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  1567
hgs
parents:
diff changeset
  1568
	if (!info.iBreakId) //first check if the iId address is valid
hgs
parents:
diff changeset
  1569
		return KErrArgument;
hgs
parents:
diff changeset
  1570
hgs
parents:
diff changeset
  1571
	if (err == KErrNone)
hgs
parents:
diff changeset
  1572
		{
hgs
parents:
diff changeset
  1573
		TInt32 iBreakId;
hgs
parents:
diff changeset
  1574
hgs
parents:
diff changeset
  1575
		err = iBreakManager->DoSetBreak(iBreakId, info.iId, info.iThreadSpecific, info.iAddress, info.iMode );
hgs
parents:
diff changeset
  1576
hgs
parents:
diff changeset
  1577
		if (err == KErrNone)
hgs
parents:
diff changeset
  1578
			{
hgs
parents:
diff changeset
  1579
			err = Kern::ThreadRawWrite(iClientThread, (TUint8 *)info.iBreakId, &iBreakId, sizeof(TInt32), iClientThread);
hgs
parents:
diff changeset
  1580
			}
hgs
parents:
diff changeset
  1581
		}
hgs
parents:
diff changeset
  1582
hgs
parents:
diff changeset
  1583
	return err;
hgs
parents:
diff changeset
  1584
	}
hgs
parents:
diff changeset
  1585
hgs
parents:
diff changeset
  1586
//
hgs
parents:
diff changeset
  1587
// DRM_DebugChannel::StepRange
hgs
parents:
diff changeset
  1588
//
hgs
parents:
diff changeset
  1589
TInt DRM_DebugChannel::StepRange(DThread* aThread, TRM_DebugStepInfo* aStepInfo)
hgs
parents:
diff changeset
  1590
	{
hgs
parents:
diff changeset
  1591
	LOG_MSG("DRM_DebugChannel::StepRange()");
hgs
parents:
diff changeset
  1592
hgs
parents:
diff changeset
  1593
	TInt err = KErrNone;
hgs
parents:
diff changeset
  1594
hgs
parents:
diff changeset
  1595
	if (!aStepInfo)
hgs
parents:
diff changeset
  1596
		return KErrArgument;
hgs
parents:
diff changeset
  1597
hgs
parents:
diff changeset
  1598
	TRM_DebugStepInfo info(0, 0, 0);
hgs
parents:
diff changeset
  1599
	err = Kern::ThreadRawRead(iClientThread, aStepInfo, (TUint8*)&info, sizeof(TRM_DebugStepInfo));
hgs
parents:
diff changeset
  1600
hgs
parents:
diff changeset
  1601
	if (err != KErrNone)
hgs
parents:
diff changeset
  1602
		return err;
hgs
parents:
diff changeset
  1603
hgs
parents:
diff changeset
  1604
	err = DoStepRange(aThread, info.iStartAddress, info.iStopAddress, info.iStepInto, EFalse, ETrue);
hgs
parents:
diff changeset
  1605
hgs
parents:
diff changeset
  1606
	return err;
hgs
parents:
diff changeset
  1607
	}
hgs
parents:
diff changeset
  1608
hgs
parents:
diff changeset
  1609
/**
hgs
parents:
diff changeset
  1610
Read memory from a target thread and return the data to the client. If the
hgs
parents:
diff changeset
  1611
memory block has breakpoints in it then the correct values are placed in the
hgs
parents:
diff changeset
  1612
returned data
hgs
parents:
diff changeset
  1613
hgs
parents:
diff changeset
  1614
@param aThread pointer to thread whose memory space the memory is to be read from
hgs
parents:
diff changeset
  1615
@param aMemoryInfo information about what memory to read
hgs
parents:
diff changeset
  1616
hgs
parents:
diff changeset
  1617
@return KErrNone if memory read successfully,
hgs
parents:
diff changeset
  1618
        KErrArgument if aMemoryInfo is not initialised correctly,
hgs
parents:
diff changeset
  1619
        KErrNoMemory if a temporary buffer could not be allocated,
hgs
parents:
diff changeset
  1620
        KErrBadHandle if aThread is invalid,
hgs
parents:
diff changeset
  1621
        or another of the system wide error codes
hgs
parents:
diff changeset
  1622
*/
hgs
parents:
diff changeset
  1623
TInt DRM_DebugChannel::ReadMemory(DThread* aThread, TRM_DebugMemoryInfo* aMemoryInfo)
hgs
parents:
diff changeset
  1624
	{
hgs
parents:
diff changeset
  1625
	LOG_MSG("DRM_DebugChannel::ReadMemory()");
hgs
parents:
diff changeset
  1626
hgs
parents:
diff changeset
  1627
	TInt err = KErrNone;
hgs
parents:
diff changeset
  1628
hgs
parents:
diff changeset
  1629
	if (!aMemoryInfo)
hgs
parents:
diff changeset
  1630
		return KErrArgument;
hgs
parents:
diff changeset
  1631
hgs
parents:
diff changeset
  1632
	TRM_DebugMemoryInfo info(0, 0, 0);
hgs
parents:
diff changeset
  1633
	err = Kern::ThreadRawRead(iClientThread, aMemoryInfo, (TUint8*)&info, sizeof(TRM_DebugMemoryInfo));
hgs
parents:
diff changeset
  1634
	if (err != KErrNone)
hgs
parents:
diff changeset
  1635
		{
hgs
parents:
diff changeset
  1636
		LOG_MSG2("DRM_DebugChannel::ReadMemory returning error %d after Kern::ThreadRawRead()", err);
hgs
parents:
diff changeset
  1637
		return err;
hgs
parents:
diff changeset
  1638
		}
hgs
parents:
diff changeset
  1639
hgs
parents:
diff changeset
  1640
	if (!info.iData)
hgs
parents:
diff changeset
  1641
		return KErrArgument;
hgs
parents:
diff changeset
  1642
hgs
parents:
diff changeset
  1643
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  1644
	TUint8 *data = (TUint8*)Kern::Alloc(info.iLength);
hgs
parents:
diff changeset
  1645
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  1646
	if (!data)
hgs
parents:
diff changeset
  1647
		{
hgs
parents:
diff changeset
  1648
		return KErrNoMemory;
hgs
parents:
diff changeset
  1649
		}
hgs
parents:
diff changeset
  1650
hgs
parents:
diff changeset
  1651
	TPtr8 dataDes(data, info.iLength);
hgs
parents:
diff changeset
  1652
hgs
parents:
diff changeset
  1653
	err = DoReadMemory(aThread, info.iAddress, info.iLength, dataDes);
hgs
parents:
diff changeset
  1654
	if (err == KErrNone)
hgs
parents:
diff changeset
  1655
		{
hgs
parents:
diff changeset
  1656
		err = Kern::ThreadDesWrite(iClientThread, info.iData, dataDes, 0, KChunkShiftBy0, iClientThread);
hgs
parents:
diff changeset
  1657
		if (err)
hgs
parents:
diff changeset
  1658
			{
hgs
parents:
diff changeset
  1659
			LOG_MSG2("DRM_DebugChannel::ReadMemory - Kern::ThreadDesWrite() returned error %d", err);
hgs
parents:
diff changeset
  1660
			}
hgs
parents:
diff changeset
  1661
		}
hgs
parents:
diff changeset
  1662
hgs
parents:
diff changeset
  1663
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  1664
	Kern::Free(data);
hgs
parents:
diff changeset
  1665
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  1666
hgs
parents:
diff changeset
  1667
	return err;
hgs
parents:
diff changeset
  1668
	}
hgs
parents:
diff changeset
  1669
hgs
parents:
diff changeset
  1670
/**
hgs
parents:
diff changeset
  1671
Attempt to write memory to aThread's address space
hgs
parents:
diff changeset
  1672
hgs
parents:
diff changeset
  1673
@param aThread thread to whose address space memory is to be written
hgs
parents:
diff changeset
  1674
@param aMemoryInfo memory info object representing the data to write
hgs
parents:
diff changeset
  1675
hgs
parents:
diff changeset
  1676
@return KErrNone if memory written successfully,
hgs
parents:
diff changeset
  1677
        KErrNoMemory if memory could not be allocated
hgs
parents:
diff changeset
  1678
        KErrArgument if aMemoryInfo is NULL, if aMemoryInfo.iData is NULL,
hgs
parents:
diff changeset
  1679
        if aMemoryInfo.iLength is greater than than the length of the passed
hgs
parents:
diff changeset
  1680
        in descrptor
hgs
parents:
diff changeset
  1681
        KErrBadHandle if aThread is invalid,
hgs
parents:
diff changeset
  1682
	or another of the system wide error codes
hgs
parents:
diff changeset
  1683
*/
hgs
parents:
diff changeset
  1684
TInt DRM_DebugChannel::WriteMemory(DThread* aThread, TRM_DebugMemoryInfo* aMemoryInfo)
hgs
parents:
diff changeset
  1685
	{
hgs
parents:
diff changeset
  1686
	LOG_MSG("DRM_DebugChannel::WriteMemory()");
hgs
parents:
diff changeset
  1687
hgs
parents:
diff changeset
  1688
	TInt err = KErrNone;
hgs
parents:
diff changeset
  1689
hgs
parents:
diff changeset
  1690
	if (!aMemoryInfo)
hgs
parents:
diff changeset
  1691
		return KErrArgument;
hgs
parents:
diff changeset
  1692
hgs
parents:
diff changeset
  1693
	TRM_DebugMemoryInfo info(0, 0, 0);
hgs
parents:
diff changeset
  1694
	err = Kern::ThreadRawRead(iClientThread, aMemoryInfo, (TUint8*)&info, sizeof(TRM_DebugMemoryInfo));
hgs
parents:
diff changeset
  1695
	if (err != KErrNone)
hgs
parents:
diff changeset
  1696
		return err;
hgs
parents:
diff changeset
  1697
hgs
parents:
diff changeset
  1698
	if (!info.iData)
hgs
parents:
diff changeset
  1699
		return KErrArgument;
hgs
parents:
diff changeset
  1700
hgs
parents:
diff changeset
  1701
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  1702
	TUint8 *data = (TUint8*)Kern::Alloc(info.iLength);
hgs
parents:
diff changeset
  1703
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  1704
	if (!data)
hgs
parents:
diff changeset
  1705
		{
hgs
parents:
diff changeset
  1706
		return KErrNoMemory;
hgs
parents:
diff changeset
  1707
		}
hgs
parents:
diff changeset
  1708
hgs
parents:
diff changeset
  1709
	TPtr8 dataDes(data, info.iLength);
hgs
parents:
diff changeset
  1710
hgs
parents:
diff changeset
  1711
	err = Kern::ThreadDesRead(iClientThread, info.iData, dataDes, 0);
hgs
parents:
diff changeset
  1712
	if (err == KErrNone)
hgs
parents:
diff changeset
  1713
		{
hgs
parents:
diff changeset
  1714
		err = DoWriteMemory(aThread, info.iAddress, info.iLength, dataDes);
hgs
parents:
diff changeset
  1715
		}
hgs
parents:
diff changeset
  1716
hgs
parents:
diff changeset
  1717
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  1718
	Kern::Free(data);
hgs
parents:
diff changeset
  1719
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  1720
hgs
parents:
diff changeset
  1721
	return err;
hgs
parents:
diff changeset
  1722
	}
hgs
parents:
diff changeset
  1723
hgs
parents:
diff changeset
  1724
//
hgs
parents:
diff changeset
  1725
// DRM_DebugChannel::ReadRegisters
hgs
parents:
diff changeset
  1726
//
hgs
parents:
diff changeset
  1727
TInt DRM_DebugChannel::ReadRegistersLegacy(DThread* aThread, TRM_DebugRegisterInfo* aRegisterInfo)
hgs
parents:
diff changeset
  1728
	{
hgs
parents:
diff changeset
  1729
	LOG_MSG("DRM_DebugChannel::ReadRegistersLegacy()");
hgs
parents:
diff changeset
  1730
hgs
parents:
diff changeset
  1731
	TInt err = KErrNone;
hgs
parents:
diff changeset
  1732
hgs
parents:
diff changeset
  1733
	if (!aRegisterInfo)
hgs
parents:
diff changeset
  1734
		return KErrArgument;
hgs
parents:
diff changeset
  1735
hgs
parents:
diff changeset
  1736
	TRM_DebugRegisterInfo info(0, 0, 0);
hgs
parents:
diff changeset
  1737
	err = Kern::ThreadRawRead(iClientThread, aRegisterInfo, (TUint8*)&info, sizeof(TRM_DebugRegisterInfo));
hgs
parents:
diff changeset
  1738
	if (err != KErrNone)
hgs
parents:
diff changeset
  1739
		return err;
hgs
parents:
diff changeset
  1740
hgs
parents:
diff changeset
  1741
	if (!info.iValues)
hgs
parents:
diff changeset
  1742
		return KErrArgument;
hgs
parents:
diff changeset
  1743
hgs
parents:
diff changeset
  1744
	TUint length = (info.iLastRegister - info.iFirstRegister + 1) * 4;
hgs
parents:
diff changeset
  1745
hgs
parents:
diff changeset
  1746
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  1747
	TUint8 *values = (TUint8*)Kern::Alloc(length);
hgs
parents:
diff changeset
  1748
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  1749
	if (!values)
hgs
parents:
diff changeset
  1750
		{
hgs
parents:
diff changeset
  1751
		return KErrNoMemory;
hgs
parents:
diff changeset
  1752
		}
hgs
parents:
diff changeset
  1753
hgs
parents:
diff changeset
  1754
	TPtr8 valuesDes(values, length);
hgs
parents:
diff changeset
  1755
hgs
parents:
diff changeset
  1756
	err = DoReadRegisters(aThread, info.iFirstRegister, info.iLastRegister, valuesDes);
hgs
parents:
diff changeset
  1757
	if (err == KErrNone)
hgs
parents:
diff changeset
  1758
		{
hgs
parents:
diff changeset
  1759
		err = Kern::ThreadDesWrite(iClientThread, info.iValues, valuesDes, 0, KChunkShiftBy0, iClientThread);
hgs
parents:
diff changeset
  1760
		}
hgs
parents:
diff changeset
  1761
hgs
parents:
diff changeset
  1762
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  1763
	Kern::Free(values);
hgs
parents:
diff changeset
  1764
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  1765
hgs
parents:
diff changeset
  1766
	return err;
hgs
parents:
diff changeset
  1767
	}
hgs
parents:
diff changeset
  1768
hgs
parents:
diff changeset
  1769
/**
hgs
parents:
diff changeset
  1770
Get listing information.
hgs
parents:
diff changeset
  1771
hgs
parents:
diff changeset
  1772
@param aListInformation pointer to a TListInformation object containing the
hgs
parents:
diff changeset
  1773
       user specified listings information
hgs
parents:
diff changeset
  1774
hgs
parents:
diff changeset
  1775
@return KErrNone on success,
hgs
parents:
diff changeset
  1776
        KErrTooBig if the kernel's data is too big to fit in the passed buffer,
hgs
parents:
diff changeset
  1777
        KErrArgument if aListInformation is NULL,
hgs
parents:
diff changeset
  1778
	or one of the other system-wide error codes
hgs
parents:
diff changeset
  1779
*/
hgs
parents:
diff changeset
  1780
TInt DRM_DebugChannel::GetList(TListInformation* aListInformation) const
hgs
parents:
diff changeset
  1781
	{
hgs
parents:
diff changeset
  1782
	LOG_MSG("DRM_DebugChannel::GetList()");
hgs
parents:
diff changeset
  1783
hgs
parents:
diff changeset
  1784
	TInt err = KErrNone;
hgs
parents:
diff changeset
  1785
hgs
parents:
diff changeset
  1786
	if(aListInformation == NULL)
hgs
parents:
diff changeset
  1787
		{
hgs
parents:
diff changeset
  1788
		return KErrArgument;
hgs
parents:
diff changeset
  1789
		}
hgs
parents:
diff changeset
  1790
hgs
parents:
diff changeset
  1791
	//read DSS' data into local structure
hgs
parents:
diff changeset
  1792
	TListInformation info;
hgs
parents:
diff changeset
  1793
	err = Kern::ThreadRawRead(iClientThread, aListInformation, (TUint8*)&info, sizeof(TListInformation));
hgs
parents:
diff changeset
  1794
	if(err != KErrNone)
hgs
parents:
diff changeset
  1795
		{
hgs
parents:
diff changeset
  1796
		return err;
hgs
parents:
diff changeset
  1797
		}
hgs
parents:
diff changeset
  1798
hgs
parents:
diff changeset
  1799
	//check arguments
hgs
parents:
diff changeset
  1800
	TPtr8 buffer(NULL, 0);
hgs
parents:
diff changeset
  1801
	err = AllocAndReadDes(iClientThread, *info.iBuffer, buffer);
hgs
parents:
diff changeset
  1802
	if(err != KErrNone)
hgs
parents:
diff changeset
  1803
		{
hgs
parents:
diff changeset
  1804
		//need to free the buffer if it was allocated
hgs
parents:
diff changeset
  1805
		if(err != KErrNoMemory)
hgs
parents:
diff changeset
  1806
			{
hgs
parents:
diff changeset
  1807
			NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  1808
			Kern::Free((TAny*)buffer.Ptr());
hgs
parents:
diff changeset
  1809
			NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  1810
			}
hgs
parents:
diff changeset
  1811
		return err;
hgs
parents:
diff changeset
  1812
		}
hgs
parents:
diff changeset
  1813
hgs
parents:
diff changeset
  1814
	//get the list
hgs
parents:
diff changeset
  1815
	TUint32 dataSize = 0;
hgs
parents:
diff changeset
  1816
	TListManager manager;
hgs
parents:
diff changeset
  1817
	err = KErrArgument;
hgs
parents:
diff changeset
  1818
	switch(info.iType)
hgs
parents:
diff changeset
  1819
		{
hgs
parents:
diff changeset
  1820
		case EXipLibraries:
hgs
parents:
diff changeset
  1821
			if(Debug::EScopeGlobal == info.iListScope)
hgs
parents:
diff changeset
  1822
				{
hgs
parents:
diff changeset
  1823
				err = manager.GetXipLibrariesList(buffer, dataSize);
hgs
parents:
diff changeset
  1824
				}
hgs
parents:
diff changeset
  1825
			break;
hgs
parents:
diff changeset
  1826
hgs
parents:
diff changeset
  1827
		case EThreads:
hgs
parents:
diff changeset
  1828
			if(Debug::EScopeGlobal == info.iListScope)
hgs
parents:
diff changeset
  1829
				{
hgs
parents:
diff changeset
  1830
				err = manager.GetGlobalThreadList(buffer, dataSize);
hgs
parents:
diff changeset
  1831
				}
hgs
parents:
diff changeset
  1832
			else if(Debug::EScopeProcessSpecific == info.iListScope)
hgs
parents:
diff changeset
  1833
				{
hgs
parents:
diff changeset
  1834
				err = manager.GetThreadListForProcess(buffer, dataSize, info.iTargetId);
hgs
parents:
diff changeset
  1835
				}
hgs
parents:
diff changeset
  1836
			else if(Debug::EScopeThreadSpecific == info.iListScope)
hgs
parents:
diff changeset
  1837
				{
hgs
parents:
diff changeset
  1838
				err = manager.GetThreadListForThread(buffer, dataSize, info.iTargetId);
hgs
parents:
diff changeset
  1839
				}
hgs
parents:
diff changeset
  1840
			break;
hgs
parents:
diff changeset
  1841
hgs
parents:
diff changeset
  1842
		case EProcesses:
hgs
parents:
diff changeset
  1843
			if(Debug::EScopeGlobal == info.iListScope)
hgs
parents:
diff changeset
  1844
				{
hgs
parents:
diff changeset
  1845
				err = manager.GetProcessList(buffer, dataSize);
hgs
parents:
diff changeset
  1846
				}
hgs
parents:
diff changeset
  1847
			break;
hgs
parents:
diff changeset
  1848
hgs
parents:
diff changeset
  1849
		case ECodeSegs:
hgs
parents:
diff changeset
  1850
			if(Debug::EScopeGlobal == info.iListScope)
hgs
parents:
diff changeset
  1851
				{
hgs
parents:
diff changeset
  1852
				err = manager.GetGlobalCodeSegList(buffer, dataSize);
hgs
parents:
diff changeset
  1853
				}
hgs
parents:
diff changeset
  1854
			else if(Debug::EScopeProcessSpecific == info.iListScope)
hgs
parents:
diff changeset
  1855
				{
hgs
parents:
diff changeset
  1856
				err = manager.GetCodeSegListForProcess(buffer, dataSize, info.iTargetId);
hgs
parents:
diff changeset
  1857
				}
hgs
parents:
diff changeset
  1858
			else if(Debug::EScopeThreadSpecific == info.iListScope)
hgs
parents:
diff changeset
  1859
				{
hgs
parents:
diff changeset
  1860
				err = manager.GetCodeSegListForThread(buffer, dataSize, info.iTargetId);
hgs
parents:
diff changeset
  1861
				}
hgs
parents:
diff changeset
  1862
			break;
hgs
parents:
diff changeset
  1863
hgs
parents:
diff changeset
  1864
		default:
hgs
parents:
diff changeset
  1865
			err = KErrNotSupported;
hgs
parents:
diff changeset
  1866
		}
hgs
parents:
diff changeset
  1867
hgs
parents:
diff changeset
  1868
	if(err == KErrNone)
hgs
parents:
diff changeset
  1869
		{
hgs
parents:
diff changeset
  1870
		//if no error then write the buffer back
hgs
parents:
diff changeset
  1871
		err = Kern::ThreadDesWrite(iClientThread, info.iBuffer, buffer, 0, KChunkShiftBy0, iClientThread);
hgs
parents:
diff changeset
  1872
		}
hgs
parents:
diff changeset
  1873
hgs
parents:
diff changeset
  1874
	//write back the size of the data regardless of any error
hgs
parents:
diff changeset
  1875
	TInt writeErr = Kern::ThreadRawWrite(iClientThread, info.iDataSize, (TUint8*)&dataSize, sizeof(TUint32), iClientThread);
hgs
parents:
diff changeset
  1876
	if(writeErr != KErrNone)
hgs
parents:
diff changeset
  1877
		{
hgs
parents:
diff changeset
  1878
		//if there was an error writing the size return that error instead
hgs
parents:
diff changeset
  1879
		err = writeErr;
hgs
parents:
diff changeset
  1880
		}
hgs
parents:
diff changeset
  1881
hgs
parents:
diff changeset
  1882
	//free the buffer
hgs
parents:
diff changeset
  1883
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  1884
	Kern::Free((TAny*)buffer.Ptr());
hgs
parents:
diff changeset
  1885
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  1886
hgs
parents:
diff changeset
  1887
	return err;
hgs
parents:
diff changeset
  1888
	}
hgs
parents:
diff changeset
  1889
hgs
parents:
diff changeset
  1890
/**
hgs
parents:
diff changeset
  1891
Read registers and store register data in aRegisterInfo
hgs
parents:
diff changeset
  1892
hgs
parents:
diff changeset
  1893
@param aThread thread to read registers from
hgs
parents:
diff changeset
  1894
@param aRegisterInfo structure specifying which registers to read and providing
hgs
parents:
diff changeset
  1895
       descriptors to write the register data into
hgs
parents:
diff changeset
  1896
hgs
parents:
diff changeset
  1897
@return KErrNone if registers were read successfully. Note that this does not
hgs
parents:
diff changeset
  1898
        mean that all the registers could be read, the
hgs
parents:
diff changeset
  1899
        aRegisterInfo.iRegisterFlags array should be checked as to whether each
hgs
parents:
diff changeset
  1900
        individual register could be read,
hgs
parents:
diff changeset
  1901
        KErrArgument if aRegisterInfo is NULL, or if any of the pointers that
hgs
parents:
diff changeset
  1902
        are members of aRegisterInfo are NULL, if an unknown register is
hgs
parents:
diff changeset
  1903
        specified or if the passed in register values buffer is too small
hgs
parents:
diff changeset
  1904
        KErrNoMemory if there is insufficient memory,
hgs
parents:
diff changeset
  1905
        KErrDied, if the thread with thread ID aThreadId is dead
hgs
parents:
diff changeset
  1906
*/
hgs
parents:
diff changeset
  1907
TInt DRM_DebugChannel::ReadRegisters(DThread* aThread, TRM_DebugRegisterInformation* aRegisterInfo) const
hgs
parents:
diff changeset
  1908
	{
hgs
parents:
diff changeset
  1909
	LOG_MSG("DRM_DebugChannel::ReadRegisters()");
hgs
parents:
diff changeset
  1910
hgs
parents:
diff changeset
  1911
	TInt err = KErrNone;
hgs
parents:
diff changeset
  1912
hgs
parents:
diff changeset
  1913
	if (!aRegisterInfo)
hgs
parents:
diff changeset
  1914
		return KErrArgument;
hgs
parents:
diff changeset
  1915
hgs
parents:
diff changeset
  1916
	TRM_DebugRegisterInformation info;
hgs
parents:
diff changeset
  1917
	err = Kern::ThreadRawRead(iClientThread, aRegisterInfo, (TUint8*)&info, sizeof(TRM_DebugRegisterInformation));
hgs
parents:
diff changeset
  1918
	if (err != KErrNone)
hgs
parents:
diff changeset
  1919
		return err;
hgs
parents:
diff changeset
  1920
hgs
parents:
diff changeset
  1921
	if ((!info.iRegisterIds) || (!info.iRegisterValues) || (!info.iRegisterFlags))
hgs
parents:
diff changeset
  1922
		return KErrArgument;
hgs
parents:
diff changeset
  1923
hgs
parents:
diff changeset
  1924
	//read ids from client thread
hgs
parents:
diff changeset
  1925
	TPtr8 ids(NULL, 0);
hgs
parents:
diff changeset
  1926
	err = AllocAndReadDes(iClientThread, *info.iRegisterIds, ids);
hgs
parents:
diff changeset
  1927
	if(err != KErrNone)
hgs
parents:
diff changeset
  1928
		{
hgs
parents:
diff changeset
  1929
		if(err == KErrNoMemory)
hgs
parents:
diff changeset
  1930
			{
hgs
parents:
diff changeset
  1931
			NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  1932
			Kern::Free((TAny*)ids.Ptr());
hgs
parents:
diff changeset
  1933
			NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  1934
			}
hgs
parents:
diff changeset
  1935
		return err;
hgs
parents:
diff changeset
  1936
		}
hgs
parents:
diff changeset
  1937
hgs
parents:
diff changeset
  1938
	//read values from client thread
hgs
parents:
diff changeset
  1939
	TPtr8 values(NULL, 0);
hgs
parents:
diff changeset
  1940
	err = AllocAndReadDes(iClientThread, *info.iRegisterValues, values, EFalse);
hgs
parents:
diff changeset
  1941
	if(err != KErrNone)
hgs
parents:
diff changeset
  1942
		{
hgs
parents:
diff changeset
  1943
		if(err == KErrNoMemory)
hgs
parents:
diff changeset
  1944
			{
hgs
parents:
diff changeset
  1945
			NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  1946
			Kern::Free((TAny*)values.Ptr());
hgs
parents:
diff changeset
  1947
			NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  1948
			}
hgs
parents:
diff changeset
  1949
hgs
parents:
diff changeset
  1950
		NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  1951
		Kern::Free((TAny*)ids.Ptr());
hgs
parents:
diff changeset
  1952
		NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  1953
		return err;
hgs
parents:
diff changeset
  1954
		}
hgs
parents:
diff changeset
  1955
hgs
parents:
diff changeset
  1956
	//read flags from client thread
hgs
parents:
diff changeset
  1957
	TPtr8 flags(NULL, 0);
hgs
parents:
diff changeset
  1958
	err = AllocAndReadDes(iClientThread, *info.iRegisterFlags, flags, EFalse);
hgs
parents:
diff changeset
  1959
	if(err != KErrNone)
hgs
parents:
diff changeset
  1960
		{
hgs
parents:
diff changeset
  1961
		if(err == KErrNoMemory)
hgs
parents:
diff changeset
  1962
			{
hgs
parents:
diff changeset
  1963
			NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  1964
			Kern::Free((TAny*)flags.Ptr());
hgs
parents:
diff changeset
  1965
			NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  1966
			}
hgs
parents:
diff changeset
  1967
		NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  1968
		Kern::Free((TAny*)ids.Ptr());
hgs
parents:
diff changeset
  1969
		Kern::Free((TAny*)values.Ptr());
hgs
parents:
diff changeset
  1970
		NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  1971
		return err;
hgs
parents:
diff changeset
  1972
		}
hgs
parents:
diff changeset
  1973
hgs
parents:
diff changeset
  1974
	err = DoReadRegisters(aThread, ids, values, flags);
hgs
parents:
diff changeset
  1975
	if (err == KErrNone)
hgs
parents:
diff changeset
  1976
		{
hgs
parents:
diff changeset
  1977
		err = Kern::ThreadDesWrite(iClientThread, info.iRegisterValues, values, 0, KChunkShiftBy0, iClientThread);
hgs
parents:
diff changeset
  1978
		if(err == KErrNone)
hgs
parents:
diff changeset
  1979
			{
hgs
parents:
diff changeset
  1980
			err = Kern::ThreadDesWrite(iClientThread, info.iRegisterFlags, flags, 0, KChunkShiftBy0, iClientThread);
hgs
parents:
diff changeset
  1981
			}
hgs
parents:
diff changeset
  1982
		}
hgs
parents:
diff changeset
  1983
hgs
parents:
diff changeset
  1984
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  1985
	Kern::Free((TAny*)ids.Ptr());
hgs
parents:
diff changeset
  1986
	Kern::Free((TAny*)values.Ptr());
hgs
parents:
diff changeset
  1987
	Kern::Free((TAny*)flags.Ptr());
hgs
parents:
diff changeset
  1988
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  1989
hgs
parents:
diff changeset
  1990
	return err;
hgs
parents:
diff changeset
  1991
	}
hgs
parents:
diff changeset
  1992
hgs
parents:
diff changeset
  1993
/**
hgs
parents:
diff changeset
  1994
@deprecated use DRM_DebugChannel::WriteRegisters(DThread* aThread, TRM_DebugRegisterInformation* aRegisterInfo) instead
hgs
parents:
diff changeset
  1995
*/
hgs
parents:
diff changeset
  1996
TInt DRM_DebugChannel::WriteRegistersLegacy(DThread* aThread, const TRM_DebugRegisterInfo* aRegisterInfo)
hgs
parents:
diff changeset
  1997
	{
hgs
parents:
diff changeset
  1998
	LOG_MSG("DRM_DebugChannel::WriteRegistersLegacy()");
hgs
parents:
diff changeset
  1999
hgs
parents:
diff changeset
  2000
	TInt err = KErrNone;
hgs
parents:
diff changeset
  2001
hgs
parents:
diff changeset
  2002
	if (!aRegisterInfo)
hgs
parents:
diff changeset
  2003
		return KErrArgument;
hgs
parents:
diff changeset
  2004
hgs
parents:
diff changeset
  2005
	TRM_DebugRegisterInfo info(0, 0, 0);
hgs
parents:
diff changeset
  2006
	err = Kern::ThreadRawRead(iClientThread, aRegisterInfo, (TUint8*)&info, sizeof(TRM_DebugRegisterInfo));
hgs
parents:
diff changeset
  2007
	if (err != KErrNone)
hgs
parents:
diff changeset
  2008
		return err;
hgs
parents:
diff changeset
  2009
hgs
parents:
diff changeset
  2010
	if (!info.iValues)
hgs
parents:
diff changeset
  2011
		return KErrArgument;
hgs
parents:
diff changeset
  2012
hgs
parents:
diff changeset
  2013
	TUint length = (info.iLastRegister - info.iFirstRegister + 1) * 4;
hgs
parents:
diff changeset
  2014
hgs
parents:
diff changeset
  2015
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  2016
	TUint8 *values = (TUint8*)Kern::Alloc(length);
hgs
parents:
diff changeset
  2017
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  2018
	if (!values)
hgs
parents:
diff changeset
  2019
		{
hgs
parents:
diff changeset
  2020
		return KErrNoMemory;
hgs
parents:
diff changeset
  2021
		}
hgs
parents:
diff changeset
  2022
hgs
parents:
diff changeset
  2023
	TPtr8 valuesDes(values, length);
hgs
parents:
diff changeset
  2024
hgs
parents:
diff changeset
  2025
	err = Kern::ThreadDesRead(iClientThread, info.iValues, valuesDes, 0);
hgs
parents:
diff changeset
  2026
	if (err == KErrNone)
hgs
parents:
diff changeset
  2027
		{
hgs
parents:
diff changeset
  2028
		err = DoWriteRegisters(aThread, info.iFirstRegister, info.iLastRegister, valuesDes);
hgs
parents:
diff changeset
  2029
		}
hgs
parents:
diff changeset
  2030
hgs
parents:
diff changeset
  2031
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  2032
	Kern::Free(values);
hgs
parents:
diff changeset
  2033
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  2034
hgs
parents:
diff changeset
  2035
	return err;
hgs
parents:
diff changeset
  2036
	}
hgs
parents:
diff changeset
  2037
hgs
parents:
diff changeset
  2038
/**
hgs
parents:
diff changeset
  2039
Write registers and store flags data in aRegisterInfo
hgs
parents:
diff changeset
  2040
hgs
parents:
diff changeset
  2041
@param aThread thread to write registers to
hgs
parents:
diff changeset
  2042
@param aRegisterInfo structure specifying which registers to write and providing
hgs
parents:
diff changeset
  2043
       descriptors to write the register flags data into
hgs
parents:
diff changeset
  2044
hgs
parents:
diff changeset
  2045
@return KErrNone if registers were written successfully. Note that this does not
hgs
parents:
diff changeset
  2046
        mean that all the registers could be written, the flags array
hgs
parents:
diff changeset
  2047
        should be checked as to whether each individual register could be read,
hgs
parents:
diff changeset
  2048
        KErrArgument if aRegisterInfo is NULL, or if any of the pointers that
hgs
parents:
diff changeset
  2049
        are members of aRegisterInfo are NULL, if an unknown register is
hgs
parents:
diff changeset
  2050
        specified or if the passed in register values buffer is too small, or
hgs
parents:
diff changeset
  2051
        if aThread is NULL,
hgs
parents:
diff changeset
  2052
        KErrGeneral if there was a problem initialising the register set,
hgs
parents:
diff changeset
  2053
        KErrNoMemory if there is insufficient memory,
hgs
parents:
diff changeset
  2054
        KErrDied, if the thread with thread ID aThreadId is dead
hgs
parents:
diff changeset
  2055
*/
hgs
parents:
diff changeset
  2056
TInt DRM_DebugChannel::WriteRegisters(DThread* aThread, TRM_DebugRegisterInformation* aRegisterInfo) const
hgs
parents:
diff changeset
  2057
	{
hgs
parents:
diff changeset
  2058
	LOG_MSG("DRM_DebugChannel::WriteRegisters()");
hgs
parents:
diff changeset
  2059
hgs
parents:
diff changeset
  2060
	TInt err = KErrNone;
hgs
parents:
diff changeset
  2061
hgs
parents:
diff changeset
  2062
	if (!aRegisterInfo)
hgs
parents:
diff changeset
  2063
		return KErrArgument;
hgs
parents:
diff changeset
  2064
hgs
parents:
diff changeset
  2065
	TRM_DebugRegisterInformation info;
hgs
parents:
diff changeset
  2066
	err = Kern::ThreadRawRead(iClientThread, aRegisterInfo, (TUint8*)&info, sizeof(TRM_DebugRegisterInformation));
hgs
parents:
diff changeset
  2067
	if (err != KErrNone)
hgs
parents:
diff changeset
  2068
		return err;
hgs
parents:
diff changeset
  2069
hgs
parents:
diff changeset
  2070
	if ((!info.iRegisterIds) || (!info.iRegisterValues) ||(!info.iRegisterFlags))
hgs
parents:
diff changeset
  2071
		return KErrArgument;
hgs
parents:
diff changeset
  2072
hgs
parents:
diff changeset
  2073
	//read ids from client thread
hgs
parents:
diff changeset
  2074
	TPtr8 ids(NULL, 0);
hgs
parents:
diff changeset
  2075
	err = AllocAndReadDes(iClientThread, *info.iRegisterIds, ids);
hgs
parents:
diff changeset
  2076
	if(err != KErrNone)
hgs
parents:
diff changeset
  2077
		{
hgs
parents:
diff changeset
  2078
		if(err == KErrNoMemory)
hgs
parents:
diff changeset
  2079
			{
hgs
parents:
diff changeset
  2080
			NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  2081
			Kern::Free((TAny*)ids.Ptr());
hgs
parents:
diff changeset
  2082
			NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  2083
			}
hgs
parents:
diff changeset
  2084
		return err;
hgs
parents:
diff changeset
  2085
		}
hgs
parents:
diff changeset
  2086
hgs
parents:
diff changeset
  2087
	//read values from client thread
hgs
parents:
diff changeset
  2088
	TPtr8 values(NULL, 0);
hgs
parents:
diff changeset
  2089
	err = AllocAndReadDes(iClientThread, *info.iRegisterValues, values);
hgs
parents:
diff changeset
  2090
	if(err != KErrNone)
hgs
parents:
diff changeset
  2091
		{
hgs
parents:
diff changeset
  2092
		if(err == KErrNoMemory)
hgs
parents:
diff changeset
  2093
			{
hgs
parents:
diff changeset
  2094
			NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  2095
			Kern::Free((TAny*)values.Ptr());
hgs
parents:
diff changeset
  2096
			NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  2097
			}
hgs
parents:
diff changeset
  2098
		NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  2099
		Kern::Free((TAny*)ids.Ptr());
hgs
parents:
diff changeset
  2100
		NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  2101
		return err;
hgs
parents:
diff changeset
  2102
		}
hgs
parents:
diff changeset
  2103
hgs
parents:
diff changeset
  2104
	//read flags from client thread
hgs
parents:
diff changeset
  2105
	TPtr8 flags(NULL, 0);
hgs
parents:
diff changeset
  2106
	err = AllocAndReadDes(iClientThread, *info.iRegisterFlags, flags, EFalse);
hgs
parents:
diff changeset
  2107
	if(err != KErrNone)
hgs
parents:
diff changeset
  2108
		{
hgs
parents:
diff changeset
  2109
		if(err == KErrNoMemory)
hgs
parents:
diff changeset
  2110
			{
hgs
parents:
diff changeset
  2111
			NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  2112
			Kern::Free((TAny*)flags.Ptr());
hgs
parents:
diff changeset
  2113
			NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  2114
			}
hgs
parents:
diff changeset
  2115
		NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  2116
		Kern::Free((TAny*)ids.Ptr());
hgs
parents:
diff changeset
  2117
		Kern::Free((TAny*)values.Ptr());
hgs
parents:
diff changeset
  2118
		NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  2119
		return err;
hgs
parents:
diff changeset
  2120
		}
hgs
parents:
diff changeset
  2121
hgs
parents:
diff changeset
  2122
	err = DoWriteRegisters(aThread, ids, values, flags);
hgs
parents:
diff changeset
  2123
	if(err == KErrNone)
hgs
parents:
diff changeset
  2124
		{
hgs
parents:
diff changeset
  2125
		err = Kern::ThreadDesWrite(iClientThread, info.iRegisterFlags, flags, 0, KChunkShiftBy0, iClientThread);
hgs
parents:
diff changeset
  2126
		}
hgs
parents:
diff changeset
  2127
hgs
parents:
diff changeset
  2128
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  2129
	Kern::Free((TAny*)ids.Ptr());
hgs
parents:
diff changeset
  2130
	Kern::Free((TAny*)values.Ptr());
hgs
parents:
diff changeset
  2131
	Kern::Free((TAny*)flags.Ptr());
hgs
parents:
diff changeset
  2132
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  2133
hgs
parents:
diff changeset
  2134
	return err;
hgs
parents:
diff changeset
  2135
	}
hgs
parents:
diff changeset
  2136
hgs
parents:
diff changeset
  2137
/**
hgs
parents:
diff changeset
  2138
Suspends execution of the specified thread.
hgs
parents:
diff changeset
  2139
hgs
parents:
diff changeset
  2140
@param aThread thread to resume
hgs
parents:
diff changeset
  2141
hgs
parents:
diff changeset
  2142
@return KErrNone if there were no problems or KErrArgument if aThread is NULL
hgs
parents:
diff changeset
  2143
*/
hgs
parents:
diff changeset
  2144
TInt DRM_DebugChannel::DoSuspendThread(DThread *aThread)
hgs
parents:
diff changeset
  2145
	{
hgs
parents:
diff changeset
  2146
	LOG_MSG("DRM_DebugChannel::DoSuspendThread()");
hgs
parents:
diff changeset
  2147
hgs
parents:
diff changeset
  2148
	if (!aThread)
hgs
parents:
diff changeset
  2149
		{
hgs
parents:
diff changeset
  2150
		LOG_MSG("Invalid dthread object");
hgs
parents:
diff changeset
  2151
		return KErrArgument;
hgs
parents:
diff changeset
  2152
		}
hgs
parents:
diff changeset
  2153
hgs
parents:
diff changeset
  2154
	return TheDProcessTracker.SuspendThread(aThread);
hgs
parents:
diff changeset
  2155
	}
hgs
parents:
diff changeset
  2156
hgs
parents:
diff changeset
  2157
/**
hgs
parents:
diff changeset
  2158
Resumes execution of the specified thread.
hgs
parents:
diff changeset
  2159
hgs
parents:
diff changeset
  2160
@param aThread thread to resume
hgs
parents:
diff changeset
  2161
hgs
parents:
diff changeset
  2162
@return KErrNone if there were no problems, KErrArgument if aThread is NULL
hgs
parents:
diff changeset
  2163
        or an error value returned from DoStepRange()
hgs
parents:
diff changeset
  2164
*/
hgs
parents:
diff changeset
  2165
TInt DRM_DebugChannel::DoResumeThread(DThread *aThread)
hgs
parents:
diff changeset
  2166
	{
hgs
parents:
diff changeset
  2167
	if (!aThread)
hgs
parents:
diff changeset
  2168
		return KErrArgument;
hgs
parents:
diff changeset
  2169
hgs
parents:
diff changeset
  2170
	// get the current PC
hgs
parents:
diff changeset
  2171
	TUint32 currentPC;
hgs
parents:
diff changeset
  2172
	TInt err = ReadKernelRegisterValue(aThread, PC_REGISTER, currentPC);
hgs
parents:
diff changeset
  2173
	if(err != KErrNone)
hgs
parents:
diff changeset
  2174
		{
hgs
parents:
diff changeset
  2175
		LOG_MSG2("DRM_DebugChannel::DoResumeThread : Read PC reg error %d.", err);
hgs
parents:
diff changeset
  2176
		// Set to this value because 0 is dangerous since structures are usually 0-initialised,
hgs
parents:
diff changeset
  2177
		// and could thus lead to a false positive in tmp break loop below
hgs
parents:
diff changeset
  2178
		currentPC = 0xFFFFFFFF;
hgs
parents:
diff changeset
  2179
		}
hgs
parents:
diff changeset
  2180
	else
hgs
parents:
diff changeset
  2181
		{
hgs
parents:
diff changeset
  2182
		LOG_MSG2("DRM_DebugChannel::DoResumeThread(), pc=0x%x", currentPC);
hgs
parents:
diff changeset
  2183
		}
hgs
parents:
diff changeset
  2184
hgs
parents:
diff changeset
  2185
	// if there is a breakpoint at the current PC, we need to single step past it
hgs
parents:
diff changeset
  2186
	TBreakEntry* breakEntry = NULL;
hgs
parents:
diff changeset
  2187
	do
hgs
parents:
diff changeset
  2188
		{
hgs
parents:
diff changeset
  2189
		breakEntry = iBreakManager->GetNextBreak(breakEntry);
hgs
parents:
diff changeset
  2190
		if(breakEntry && !iBreakManager->IsTemporaryBreak(*breakEntry))
hgs
parents:
diff changeset
  2191
			{
hgs
parents:
diff changeset
  2192
			if (breakEntry->iAddress == currentPC)
hgs
parents:
diff changeset
  2193
				{
hgs
parents:
diff changeset
  2194
                LOG_MSG2("DRM_DebugChannel::DoResumeThread : > DoStepRange(pc+1)=0x%x, resume once out of range", currentPC+1 );
hgs
parents:
diff changeset
  2195
				return DoStepRange(aThread, currentPC, currentPC+1, ETrue, 1, ETrue);
hgs
parents:
diff changeset
  2196
				}
hgs
parents:
diff changeset
  2197
			}
hgs
parents:
diff changeset
  2198
		} while(breakEntry);
hgs
parents:
diff changeset
  2199
hgs
parents:
diff changeset
  2200
	return TheDProcessTracker.ResumeThread(aThread);
hgs
parents:
diff changeset
  2201
	}
hgs
parents:
diff changeset
  2202
hgs
parents:
diff changeset
  2203
//
hgs
parents:
diff changeset
  2204
// DRM_DebugChannel::DoStepRange
hgs
parents:
diff changeset
  2205
//
hgs
parents:
diff changeset
  2206
TInt DRM_DebugChannel::DoStepRange(DThread *aThread, const TUint32 aStartAddress, const TUint32 aStopAddress, TBool aStepInto, TBool aResumeOnceOutOfRange, const TUint32 aNumSteps, TBool aUserRequest)
hgs
parents:
diff changeset
  2207
	{
hgs
parents:
diff changeset
  2208
	LOG_MSG("DRM_DebugChannel::DoStepRange()");
hgs
parents:
diff changeset
  2209
hgs
parents:
diff changeset
  2210
	if (!aThread)
hgs
parents:
diff changeset
  2211
		return KErrArgument;
hgs
parents:
diff changeset
  2212
hgs
parents:
diff changeset
  2213
hgs
parents:
diff changeset
  2214
	TUint32 startAddress = (aStartAddress & 0x1) ? aStartAddress + 1 : aStartAddress;
hgs
parents:
diff changeset
  2215
	TUint32 stopAddress = (aStopAddress & 0x1) ? aStopAddress + 1 : aStopAddress;;
hgs
parents:
diff changeset
  2216
hgs
parents:
diff changeset
  2217
	// don't allow the user to step in the excluded ROM region.  this could be called
hgs
parents:
diff changeset
  2218
	// internally however.  for example, the the special breakpoints we set to handle
hgs
parents:
diff changeset
  2219
	// panics, exceptions, and library loaded events are in the user library, and we
hgs
parents:
diff changeset
  2220
	// will need to step past the breakpoint before continuing the thread.
hgs
parents:
diff changeset
  2221
	//if (aUserRequest && (startAddress >= iExcludedROMAddressStart) && (startAddress < iExcludedROMAddressEnd))
hgs
parents:
diff changeset
  2222
	//{
hgs
parents:
diff changeset
  2223
	//	return KErrNotSupported;
hgs
parents:
diff changeset
  2224
	//}
hgs
parents:
diff changeset
  2225
hgs
parents:
diff changeset
  2226
	// set the temp breakpoint, and disable the breakpoint at the current PC if necessary
hgs
parents:
diff changeset
  2227
	// if its not a user request, and we are just trying to resume from a breakpoint,
hgs
parents:
diff changeset
  2228
	// then we don't need to check for stubs. The last parameter aUserRequest tells
hgs
parents:
diff changeset
  2229
	// ModifyBreaksForStep to check for stubs or not. In some cases, the check for stubs
hgs
parents:
diff changeset
  2230
	// is true even if its not a user request.For example, this is true in cases where
hgs
parents:
diff changeset
  2231
	// we are doing a step range and the instruction in the range modified PC.
hgs
parents:
diff changeset
  2232
	// in this case, DoStepRange will be called from the exception handler where
hgs
parents:
diff changeset
  2233
	// we need to check for the stubs for the valid behavior. So truly, we don't need to check
hgs
parents:
diff changeset
  2234
	// for stubs only when resuming from  a breakpoint.
hgs
parents:
diff changeset
  2235
	ReturnIfError(iStepper->ModifyBreaksForStep(aThread, startAddress, stopAddress, aResumeOnceOutOfRange, aUserRequest, aNumSteps));
hgs
parents:
diff changeset
  2236
hgs
parents:
diff changeset
  2237
	LOG_MSG("DRM_DebugChannel::DoStepRange() - resuming thread\n");
hgs
parents:
diff changeset
  2238
hgs
parents:
diff changeset
  2239
	return TheDProcessTracker.ResumeThread(aThread);
hgs
parents:
diff changeset
  2240
	}
hgs
parents:
diff changeset
  2241
hgs
parents:
diff changeset
  2242
/**
hgs
parents:
diff changeset
  2243
Read memory from the specified addres into the aData descriptor. If there is a
hgs
parents:
diff changeset
  2244
breakpoint set in the region of memory returned then the correct data value is
hgs
parents:
diff changeset
  2245
inserted into the descriptor
hgs
parents:
diff changeset
  2246
hgs
parents:
diff changeset
  2247
@param aThread pointer to thread whose address space memory is to be read from
hgs
parents:
diff changeset
  2248
@param aAddress address to start reading memory from
hgs
parents:
diff changeset
  2249
@param aLength length of memory block to read
hgs
parents:
diff changeset
  2250
@param aData descriptor to read memory into
hgs
parents:
diff changeset
  2251
hgs
parents:
diff changeset
  2252
@return KErrNone if memory read successfully,
hgs
parents:
diff changeset
  2253
        KErrNotSupported if reading from the rom section is not supported,
hgs
parents:
diff changeset
  2254
        KErrBadHandle if aThread is invalid,
hgs
parents:
diff changeset
  2255
        or one of the other system wide error codes
hgs
parents:
diff changeset
  2256
*/
hgs
parents:
diff changeset
  2257
TInt DRM_DebugChannel::DoReadMemory(const DThread *aThread, const TUint32 aAddress, const TUint32 aLength, TDes8 &aData) const
hgs
parents:
diff changeset
  2258
	{
hgs
parents:
diff changeset
  2259
	LOG_MSG("DRM_DebugChannel::DoReadMemory()");
hgs
parents:
diff changeset
  2260
hgs
parents:
diff changeset
  2261
	// make sure the parameters are valid
hgs
parents:
diff changeset
  2262
	if (aLength > aData.MaxSize())
hgs
parents:
diff changeset
  2263
		return KErrArgument;
hgs
parents:
diff changeset
  2264
hgs
parents:
diff changeset
  2265
	TInt err = KErrNone;
hgs
parents:
diff changeset
  2266
hgs
parents:
diff changeset
  2267
	// trap exceptions in case the address is invalid
hgs
parents:
diff changeset
  2268
	XTRAPD(r, XT_DEFAULT, err = TryToReadMemory(aThread, (TAny *)aAddress, (TAny *)aData.Ptr(), aLength));
hgs
parents:
diff changeset
  2269
hgs
parents:
diff changeset
  2270
	err = (KErrNone == r) ? err : r;
hgs
parents:
diff changeset
  2271
hgs
parents:
diff changeset
  2272
	if (KErrNone == err)
hgs
parents:
diff changeset
  2273
		{
hgs
parents:
diff changeset
  2274
		aData.SetLength(aLength);
hgs
parents:
diff changeset
  2275
hgs
parents:
diff changeset
  2276
		TPtr8 data((TUint8 *)aData.Ptr(), aLength, aLength);
hgs
parents:
diff changeset
  2277
hgs
parents:
diff changeset
  2278
		// if we have any breakpoints in this range, put the actual instruction in the buffer
hgs
parents:
diff changeset
  2279
		TBreakEntry* breakEntry = NULL;
hgs
parents:
diff changeset
  2280
		do
hgs
parents:
diff changeset
  2281
			{
hgs
parents:
diff changeset
  2282
			breakEntry = iBreakManager->GetNextBreak(breakEntry);
hgs
parents:
diff changeset
  2283
			if(breakEntry && !iBreakManager->IsTemporaryBreak(*breakEntry))
hgs
parents:
diff changeset
  2284
				{
hgs
parents:
diff changeset
  2285
				if ((breakEntry->iAddress >= aAddress) && (breakEntry->iAddress < (aAddress + aLength)))
hgs
parents:
diff changeset
  2286
					{
hgs
parents:
diff changeset
  2287
					TInt instSize;
hgs
parents:
diff changeset
  2288
hgs
parents:
diff changeset
  2289
					switch(breakEntry->iMode)
hgs
parents:
diff changeset
  2290
						{
hgs
parents:
diff changeset
  2291
						case EArmMode:
hgs
parents:
diff changeset
  2292
							instSize = 4;
hgs
parents:
diff changeset
  2293
							break;
hgs
parents:
diff changeset
  2294
hgs
parents:
diff changeset
  2295
						case EThumbMode:
hgs
parents:
diff changeset
  2296
							instSize = 2;
hgs
parents:
diff changeset
  2297
							break;
hgs
parents:
diff changeset
  2298
hgs
parents:
diff changeset
  2299
						case EThumb2EEMode:
hgs
parents:
diff changeset
  2300
						default:
hgs
parents:
diff changeset
  2301
							LOG_MSG("DRM_DebugChannel::DoReadMemory() cannot fixup breakpoints with unsupported architecture");
hgs
parents:
diff changeset
  2302
							return KErrNotSupported;
hgs
parents:
diff changeset
  2303
						}
hgs
parents:
diff changeset
  2304
					memcpy((TAny*)&data[breakEntry->iAddress - aAddress], (TAny *)breakEntry->iInstruction.Ptr(), instSize);
hgs
parents:
diff changeset
  2305
					}
hgs
parents:
diff changeset
  2306
				}
hgs
parents:
diff changeset
  2307
			} while(breakEntry);
hgs
parents:
diff changeset
  2308
		}
hgs
parents:
diff changeset
  2309
hgs
parents:
diff changeset
  2310
	return err;
hgs
parents:
diff changeset
  2311
	}
hgs
parents:
diff changeset
  2312
hgs
parents:
diff changeset
  2313
/**
hgs
parents:
diff changeset
  2314
Attempt to write memory to aThread's address space
hgs
parents:
diff changeset
  2315
hgs
parents:
diff changeset
  2316
@param aThread thread to whose address space memory is to be written
hgs
parents:
diff changeset
  2317
@param aAddress memory location to write memory to
hgs
parents:
diff changeset
  2318
@param aLength number of bytes of data to write
hgs
parents:
diff changeset
  2319
@param aData descriptor containing memory to write
hgs
parents:
diff changeset
  2320
hgs
parents:
diff changeset
  2321
@return KErrNone if memory written successfully,
hgs
parents:
diff changeset
  2322
        KErrArgument if aLength is greater than than the length of the aData
hgs
parents:
diff changeset
  2323
        KErrBadHandle if aThread is invalid,
hgs
parents:
diff changeset
  2324
	or another of the system wide error codes
hgs
parents:
diff changeset
  2325
*/
hgs
parents:
diff changeset
  2326
TInt DRM_DebugChannel::DoWriteMemory(DThread *aThread, const TUint32 aAddress, const TUint32 aLength, TDes8 &aData)
hgs
parents:
diff changeset
  2327
	{
hgs
parents:
diff changeset
  2328
	LOG_MSG("DRM_DebugChannel::DoWriteMemory()");
hgs
parents:
diff changeset
  2329
hgs
parents:
diff changeset
  2330
	// make sure the parameters are valid
hgs
parents:
diff changeset
  2331
	if (aLength > aData.Length())
hgs
parents:
diff changeset
  2332
		return KErrArgument;
hgs
parents:
diff changeset
  2333
hgs
parents:
diff changeset
  2334
	TInt err = KErrNone;
hgs
parents:
diff changeset
  2335
hgs
parents:
diff changeset
  2336
	// trap exceptions in case the address is invalid
hgs
parents:
diff changeset
  2337
	XTRAPD(r, XT_DEFAULT, err = TryToWriteMemory(aThread, (TAny *)aAddress, (TAny *)aData.Ptr(), aLength));
hgs
parents:
diff changeset
  2338
hgs
parents:
diff changeset
  2339
	err = (KErrNone == r) ? err : r;
hgs
parents:
diff changeset
  2340
hgs
parents:
diff changeset
  2341
	// reset any breakpoints we may have just overwritten
hgs
parents:
diff changeset
  2342
	if (KErrNone == err)
hgs
parents:
diff changeset
  2343
		{
hgs
parents:
diff changeset
  2344
		TPtr8 data((TUint8 *)aData.Ptr(), aLength, aLength);
hgs
parents:
diff changeset
  2345
hgs
parents:
diff changeset
  2346
		TBreakEntry* breakEntry = NULL;
hgs
parents:
diff changeset
  2347
		do
hgs
parents:
diff changeset
  2348
			{
hgs
parents:
diff changeset
  2349
			breakEntry = iBreakManager->GetNextBreak(breakEntry);
hgs
parents:
diff changeset
  2350
			if(breakEntry && !iBreakManager->IsTemporaryBreak(*breakEntry))
hgs
parents:
diff changeset
  2351
				{
hgs
parents:
diff changeset
  2352
				if ((breakEntry->iAddress >= aAddress) && (breakEntry->iAddress < (aAddress + aLength)))
hgs
parents:
diff changeset
  2353
					{
hgs
parents:
diff changeset
  2354
					// default to arm mode
hgs
parents:
diff changeset
  2355
					TUint32 inst;
hgs
parents:
diff changeset
  2356
					TInt instSize;
hgs
parents:
diff changeset
  2357
hgs
parents:
diff changeset
  2358
					switch (breakEntry->iMode)
hgs
parents:
diff changeset
  2359
						{
hgs
parents:
diff changeset
  2360
						case EArmMode:
hgs
parents:
diff changeset
  2361
							inst = KArmBreakPoint;
hgs
parents:
diff changeset
  2362
							instSize = 4;
hgs
parents:
diff changeset
  2363
							break;
hgs
parents:
diff changeset
  2364
hgs
parents:
diff changeset
  2365
						case EThumbMode:
hgs
parents:
diff changeset
  2366
							inst = KThumbBreakPoint;
hgs
parents:
diff changeset
  2367
							instSize = 2;
hgs
parents:
diff changeset
  2368
							break;
hgs
parents:
diff changeset
  2369
hgs
parents:
diff changeset
  2370
						case EThumb2EEMode:
hgs
parents:
diff changeset
  2371
						default:
hgs
parents:
diff changeset
  2372
							LOG_MSG("DRM_DebugChannel::DoWriteMemory() cannot fixup breakpoints of unsupported architecture type");
hgs
parents:
diff changeset
  2373
hgs
parents:
diff changeset
  2374
							return KErrNotSupported;
hgs
parents:
diff changeset
  2375
						}
hgs
parents:
diff changeset
  2376
hgs
parents:
diff changeset
  2377
					breakEntry->iInstruction.Copy(&data[breakEntry->iAddress - aAddress], instSize);
hgs
parents:
diff changeset
  2378
					memcpy((TAny*)breakEntry->iAddress, (TAny *)&inst, instSize);
hgs
parents:
diff changeset
  2379
					}
hgs
parents:
diff changeset
  2380
				}
hgs
parents:
diff changeset
  2381
hgs
parents:
diff changeset
  2382
			} while(breakEntry);
hgs
parents:
diff changeset
  2383
		}
hgs
parents:
diff changeset
  2384
	return err;
hgs
parents:
diff changeset
  2385
	}
hgs
parents:
diff changeset
  2386
hgs
parents:
diff changeset
  2387
//
hgs
parents:
diff changeset
  2388
// DRM_DebugChannel::DoReadRegisters
hgs
parents:
diff changeset
  2389
//
hgs
parents:
diff changeset
  2390
TInt DRM_DebugChannel::DoReadRegisters(DThread *aThread, const TInt16 aFirstRegister, const TInt16 aLastRegister, TDes8 &aValues)
hgs
parents:
diff changeset
  2391
	{
hgs
parents:
diff changeset
  2392
	LOG_EVENT_MSG("DRM_DebugChannel::DoReadRegisters()");
hgs
parents:
diff changeset
  2393
hgs
parents:
diff changeset
  2394
	// make sure the parameters are valid
hgs
parents:
diff changeset
  2395
	if (!aThread || (aFirstRegister < 0) || (aLastRegister >= (TInt16)(sizeof(TArmRegSet)/sizeof(TArmReg))))
hgs
parents:
diff changeset
  2396
		return KErrArgument;
hgs
parents:
diff changeset
  2397
hgs
parents:
diff changeset
  2398
	// make sure the descriptor is big enough to hold the requested data
hgs
parents:
diff changeset
  2399
	if ((TInt)((aLastRegister - aFirstRegister + 1) * sizeof(TArmReg)) > (aValues.MaxSize()))
hgs
parents:
diff changeset
  2400
		return KErrArgument;
hgs
parents:
diff changeset
  2401
hgs
parents:
diff changeset
  2402
	TArmRegSet regSet;
hgs
parents:
diff changeset
  2403
	TUint32 unused;
hgs
parents:
diff changeset
  2404
hgs
parents:
diff changeset
  2405
	NKern::ThreadGetUserContext(&aThread->iNThread, &regSet, unused);
hgs
parents:
diff changeset
  2406
hgs
parents:
diff changeset
  2407
	LOG_MSG2( "DRM_DebugChannel::DoReadRegistersLegacy() : unused = 0x%X\n", unused );
hgs
parents:
diff changeset
  2408
hgs
parents:
diff changeset
  2409
	TArmReg *reg = &regSet.iR0;
hgs
parents:
diff changeset
  2410
hgs
parents:
diff changeset
  2411
	if (!reg)
hgs
parents:
diff changeset
  2412
		return KErrGeneral;
hgs
parents:
diff changeset
  2413
hgs
parents:
diff changeset
  2414
	for (TInt16 i = aFirstRegister; i <= aLastRegister; i++)
hgs
parents:
diff changeset
  2415
		aValues.Append((TUint8 *)&reg[i], sizeof(TArmReg));
hgs
parents:
diff changeset
  2416
hgs
parents:
diff changeset
  2417
	return KErrNone;
hgs
parents:
diff changeset
  2418
}
hgs
parents:
diff changeset
  2419
hgs
parents:
diff changeset
  2420
/**
hgs
parents:
diff changeset
  2421
  @prototype
hgs
parents:
diff changeset
  2422
hgs
parents:
diff changeset
  2423
  Experimental function for determining whether a thread is suspended.
hgs
parents:
diff changeset
  2424
hgs
parents:
diff changeset
  2425
  @param aThread thread to check if suspended
hgs
parents:
diff changeset
  2426
hgs
parents:
diff changeset
  2427
  @return ETrue if the thread is suspended, EFalse if it isn't or does not exist
hgs
parents:
diff changeset
  2428
  */
hgs
parents:
diff changeset
  2429
TBool DRM_DebugChannel::CheckSuspended(const DThread *aThread) const
hgs
parents:
diff changeset
  2430
	{
hgs
parents:
diff changeset
  2431
	if(!aThread)
hgs
parents:
diff changeset
  2432
		{
hgs
parents:
diff changeset
  2433
		return EFalse;
hgs
parents:
diff changeset
  2434
		}
hgs
parents:
diff changeset
  2435
hgs
parents:
diff changeset
  2436
	if( (aThread->iNThread.iCsCount>0) && (aThread->iNThread.iCsFunction>0) )
hgs
parents:
diff changeset
  2437
		{
hgs
parents:
diff changeset
  2438
		return ETrue;
hgs
parents:
diff changeset
  2439
		}
hgs
parents:
diff changeset
  2440
hgs
parents:
diff changeset
  2441
	if(aThread->iNThread.iSuspendCount > 0)
hgs
parents:
diff changeset
  2442
		{
hgs
parents:
diff changeset
  2443
		return ETrue;
hgs
parents:
diff changeset
  2444
		}
hgs
parents:
diff changeset
  2445
	return EFalse;
hgs
parents:
diff changeset
  2446
	}
hgs
parents:
diff changeset
  2447
hgs
parents:
diff changeset
  2448
/**
hgs
parents:
diff changeset
  2449
Read registers and store register values in aRegisterValues and the flags
hgs
parents:
diff changeset
  2450
indicating which registers could be read in aRegisterFlags
hgs
parents:
diff changeset
  2451
hgs
parents:
diff changeset
  2452
@param aThread thread to read registers from
hgs
parents:
diff changeset
  2453
@param aRegisterIds array containing register IDs to read
hgs
parents:
diff changeset
  2454
@param aRegisterValues array to store register values in
hgs
parents:
diff changeset
  2455
@param aRegisterFlags array to store flags in
hgs
parents:
diff changeset
  2456
hgs
parents:
diff changeset
  2457
@return KErrNone if registers were read successfully. Note that this does not
hgs
parents:
diff changeset
  2458
        mean that all the registers could be read, the aRegisterFlags array
hgs
parents:
diff changeset
  2459
        should be checked as to whether each individual register could be read,
hgs
parents:
diff changeset
  2460
        KErrArgument if aThread is NULL, if an unknown register is specified in
hgs
parents:
diff changeset
  2461
        aRegisterValues or if aRegisterValues is too small
hgs
parents:
diff changeset
  2462
        KErrGeneral if there was a problem initialising the register set
hgs
parents:
diff changeset
  2463
*/
hgs
parents:
diff changeset
  2464
TInt DRM_DebugChannel::DoReadRegisters(DThread *aThread, const TDesC8 &aRegisterIds, TDes8 &aRegisterValues, TDes8& aRegisterFlags) const
hgs
parents:
diff changeset
  2465
	{
hgs
parents:
diff changeset
  2466
	LOG_MSG("DRM_DebugChannel::DoReadRegisters()");
hgs
parents:
diff changeset
  2467
hgs
parents:
diff changeset
  2468
	// make sure the parameters are valid
hgs
parents:
diff changeset
  2469
	if (!aThread)
hgs
parents:
diff changeset
  2470
		return KErrArgument;
hgs
parents:
diff changeset
  2471
hgs
parents:
diff changeset
  2472
	//Need to revisit this to determine whether there is a way to validate this
hgs
parents:
diff changeset
  2473
#if 0
hgs
parents:
diff changeset
  2474
	if ( !CheckSuspended(aThread) )
hgs
parents:
diff changeset
  2475
		{
hgs
parents:
diff changeset
  2476
		LOG_MSG2("DRM_DebugChannel::DoReadRegisters() thread with id 0x%08x is not suspended", aThread->iId);
hgs
parents:
diff changeset
  2477
		return KErrInUse;
hgs
parents:
diff changeset
  2478
		}
hgs
parents:
diff changeset
  2479
#endif
hgs
parents:
diff changeset
  2480
hgs
parents:
diff changeset
  2481
	//set lengths of output descriptors to 0 prior to filling
hgs
parents:
diff changeset
  2482
	aRegisterValues.SetLength(0);
hgs
parents:
diff changeset
  2483
	aRegisterFlags.SetLength(0);
hgs
parents:
diff changeset
  2484
hgs
parents:
diff changeset
  2485
	TArmRegSet regSet;
hgs
parents:
diff changeset
  2486
	TUint32 flags;
hgs
parents:
diff changeset
  2487
hgs
parents:
diff changeset
  2488
	NKern::ThreadGetUserContext(&aThread->iNThread, &regSet, flags);
hgs
parents:
diff changeset
  2489
hgs
parents:
diff changeset
  2490
	LOG_MSG2( "DRM_DebugChannel::DoReadRegisters() : flags = 0x%X\n", flags );
hgs
parents:
diff changeset
  2491
hgs
parents:
diff changeset
  2492
	TArmReg *regPtr = &regSet.iR0;
hgs
parents:
diff changeset
  2493
hgs
parents:
diff changeset
  2494
	if (!regPtr)
hgs
parents:
diff changeset
  2495
		return KErrGeneral;
hgs
parents:
diff changeset
  2496
hgs
parents:
diff changeset
  2497
	TUint numberOfRegisters = aRegisterIds.Length() / sizeof(TRegisterInfo);
hgs
parents:
diff changeset
  2498
hgs
parents:
diff changeset
  2499
	//iterate through registers setting the relevant aFlags value
hgs
parents:
diff changeset
  2500
	for(TUint i=0; i<numberOfRegisters; i++)
hgs
parents:
diff changeset
  2501
		{
hgs
parents:
diff changeset
  2502
		//get current register id
hgs
parents:
diff changeset
  2503
		TRegisterInfo reg;
hgs
parents:
diff changeset
  2504
		TInt err = GetTRegisterInfo(aRegisterIds, i, reg);
hgs
parents:
diff changeset
  2505
		//exit with the error value if there was an error
hgs
parents:
diff changeset
  2506
		if(err != KErrNone)
hgs
parents:
diff changeset
  2507
			return err;
hgs
parents:
diff changeset
  2508
hgs
parents:
diff changeset
  2509
		//if unknown register then exit as can't know how many bytes this entry will
hgs
parents:
diff changeset
  2510
		//represent in aRegisterValues
hgs
parents:
diff changeset
  2511
		TTag registerTag;
hgs
parents:
diff changeset
  2512
		TDebugFunctionality::GetRegister(reg, registerTag);
hgs
parents:
diff changeset
  2513
		if(registerTag.iValue == EAccessUnknown)
hgs
parents:
diff changeset
  2514
			{
hgs
parents:
diff changeset
  2515
			return KErrArgument;
hgs
parents:
diff changeset
  2516
			}
hgs
parents:
diff changeset
  2517
hgs
parents:
diff changeset
  2518
		//get the current register id as a kernel register
hgs
parents:
diff changeset
  2519
		TArmReg armReg;
hgs
parents:
diff changeset
  2520
		err = GetKernelRegisterId(reg, armReg);
hgs
parents:
diff changeset
  2521
		if((err == KErrNotSupported) || (registerTag.iValue == EAccessNone) || (registerTag.iValue == EAccessWriteOnly))
hgs
parents:
diff changeset
  2522
			{
hgs
parents:
diff changeset
  2523
			//reading this register is not supported
hgs
parents:
diff changeset
  2524
			aRegisterFlags.Append(ENotSupported);
hgs
parents:
diff changeset
  2525
			//just skip over this entry in the values buffer
hgs
parents:
diff changeset
  2526
			if(aRegisterValues.Length() + registerTag.iSize > aRegisterValues.MaxLength())
hgs
parents:
diff changeset
  2527
				{
hgs
parents:
diff changeset
  2528
				//writing this value would cause overflow so exit
hgs
parents:
diff changeset
  2529
				return KErrArgument;
hgs
parents:
diff changeset
  2530
				}
hgs
parents:
diff changeset
  2531
			aRegisterValues.SetLength(aRegisterValues.Length() + registerTag.iSize);
hgs
parents:
diff changeset
  2532
			}
hgs
parents:
diff changeset
  2533
		else
hgs
parents:
diff changeset
  2534
			{
hgs
parents:
diff changeset
  2535
			if(registerTag.iSize == sizeof(TArmReg))
hgs
parents:
diff changeset
  2536
				{
hgs
parents:
diff changeset
  2537
				if(GetFlagAtOffset(flags, armReg))
hgs
parents:
diff changeset
  2538
					{
hgs
parents:
diff changeset
  2539
					//set flag as valid
hgs
parents:
diff changeset
  2540
					aRegisterFlags.Append(EValid);
hgs
parents:
diff changeset
  2541
					}
hgs
parents:
diff changeset
  2542
				else
hgs
parents:
diff changeset
  2543
					{
hgs
parents:
diff changeset
  2544
					// Even though the flag is invalid, we can return the value of the register
hgs
parents:
diff changeset
  2545
					// and let the user decide what to do
hgs
parents:
diff changeset
  2546
					aRegisterFlags.Append(EInValid);
hgs
parents:
diff changeset
  2547
					}
hgs
parents:
diff changeset
  2548
hgs
parents:
diff changeset
  2549
				if(aRegisterValues.Length() + sizeof(TArmReg) > aRegisterValues.MaxLength())
hgs
parents:
diff changeset
  2550
					{
hgs
parents:
diff changeset
  2551
					//writing this value would cause overflow so exit
hgs
parents:
diff changeset
  2552
					return KErrArgument;
hgs
parents:
diff changeset
  2553
					}
hgs
parents:
diff changeset
  2554
				//write value into register into regSet
hgs
parents:
diff changeset
  2555
				aRegisterValues.Append((TUint8 *)&regPtr[armReg], registerTag.iSize);
hgs
parents:
diff changeset
  2556
				}
hgs
parents:
diff changeset
  2557
			else
hgs
parents:
diff changeset
  2558
				{
hgs
parents:
diff changeset
  2559
				//currently all kernel supported registers are 4 bytes so
hgs
parents:
diff changeset
  2560
				//return EBadSize. Would need updating if/when other register
hgs
parents:
diff changeset
  2561
				//value sizes are supported
hgs
parents:
diff changeset
  2562
				aRegisterFlags.Append(EBadSize);
hgs
parents:
diff changeset
  2563
				aRegisterValues.SetLength(aRegisterValues.Length() + registerTag.iSize);
hgs
parents:
diff changeset
  2564
				}
hgs
parents:
diff changeset
  2565
			}
hgs
parents:
diff changeset
  2566
		}
hgs
parents:
diff changeset
  2567
	return KErrNone;
hgs
parents:
diff changeset
  2568
	}
hgs
parents:
diff changeset
  2569
hgs
parents:
diff changeset
  2570
//
hgs
parents:
diff changeset
  2571
// DRM_DebugChannel::DoWriteRegisters
hgs
parents:
diff changeset
  2572
//
hgs
parents:
diff changeset
  2573
TInt DRM_DebugChannel::DoWriteRegisters(DThread *aThread, const TInt16 aFirstRegister, const TInt16 aLastRegister, TDesC8 &aValues)
hgs
parents:
diff changeset
  2574
	{
hgs
parents:
diff changeset
  2575
	LOG_MSG("DRM_DebugChannel::DoWriteRegisters()");
hgs
parents:
diff changeset
  2576
hgs
parents:
diff changeset
  2577
	// make sure the parameters are valid
hgs
parents:
diff changeset
  2578
	if (!aThread || (aFirstRegister < 0) || (aLastRegister >= (TInt16)(sizeof(TArmRegSet)/sizeof(TArmReg))))
hgs
parents:
diff changeset
  2579
		return KErrArgument;
hgs
parents:
diff changeset
  2580
hgs
parents:
diff changeset
  2581
	// make sure the descriptor is big enough to hold the data to write
hgs
parents:
diff changeset
  2582
	if ((TInt)((aLastRegister - aFirstRegister + 1) * sizeof(TArmReg)) > (aValues.Length()))
hgs
parents:
diff changeset
  2583
		return KErrArgument;
hgs
parents:
diff changeset
  2584
hgs
parents:
diff changeset
  2585
	TArmRegSet regSet;
hgs
parents:
diff changeset
  2586
	TUint32 unused;
hgs
parents:
diff changeset
  2587
hgs
parents:
diff changeset
  2588
	NKern::ThreadGetUserContext(&aThread->iNThread, &regSet, unused);
hgs
parents:
diff changeset
  2589
hgs
parents:
diff changeset
  2590
	TArmReg *reg = &regSet.iR0;
hgs
parents:
diff changeset
  2591
hgs
parents:
diff changeset
  2592
	for (TInt16 i = aFirstRegister; i <= aLastRegister; i++)
hgs
parents:
diff changeset
  2593
		reg[i] = *(TUint32 *)&aValues[(i-aFirstRegister)*sizeof(TArmReg)];
hgs
parents:
diff changeset
  2594
hgs
parents:
diff changeset
  2595
	NKern::ThreadSetUserContext(&aThread->iNThread, &regSet);
hgs
parents:
diff changeset
  2596
hgs
parents:
diff changeset
  2597
	return KErrNone;
hgs
parents:
diff changeset
  2598
	}
hgs
parents:
diff changeset
  2599
hgs
parents:
diff changeset
  2600
/**
hgs
parents:
diff changeset
  2601
Write registers and store flags indicating which registers could be read in
hgs
parents:
diff changeset
  2602
aRegisterFlags
hgs
parents:
diff changeset
  2603
hgs
parents:
diff changeset
  2604
@param aThread thread to write registers to
hgs
parents:
diff changeset
  2605
@param aRegisterIds array containing register IDs to write
hgs
parents:
diff changeset
  2606
@param aRegisterValues array containing register values to write
hgs
parents:
diff changeset
  2607
@param aRegisterFlags array to store flags in
hgs
parents:
diff changeset
  2608
hgs
parents:
diff changeset
  2609
@return KErrNone if registers were written successfully. Note that this does not
hgs
parents:
diff changeset
  2610
        mean that all the registers could be written, the aRegisterFlags array
hgs
parents:
diff changeset
  2611
        should be checked as to whether each individual register could be read,
hgs
parents:
diff changeset
  2612
        KErrArgument if aThread is NULL, if the buffer passed in as
hgs
parents:
diff changeset
  2613
        aRegisterValue is too small, or if an unknown register is requested,
hgs
parents:
diff changeset
  2614
        KErrGeneral if there was a problem initialising the register set
hgs
parents:
diff changeset
  2615
*/
hgs
parents:
diff changeset
  2616
TInt DRM_DebugChannel::DoWriteRegisters(DThread *aThread, const TDesC8 &aRegisterIds, TDesC8 &aRegisterValues, TDes8 &aRegisterFlags) const
hgs
parents:
diff changeset
  2617
	{
hgs
parents:
diff changeset
  2618
	LOG_MSG("DRM_DebugChannel::DoWriteRegisters()");
hgs
parents:
diff changeset
  2619
hgs
parents:
diff changeset
  2620
	// make sure the parameters are valid
hgs
parents:
diff changeset
  2621
	if (!aThread)
hgs
parents:
diff changeset
  2622
		return KErrArgument;
hgs
parents:
diff changeset
  2623
hgs
parents:
diff changeset
  2624
hgs
parents:
diff changeset
  2625
	//get register values from kernel
hgs
parents:
diff changeset
  2626
	TArmRegSet regSet;
hgs
parents:
diff changeset
  2627
	TUint32 flags;
hgs
parents:
diff changeset
  2628
	NKern::ThreadGetUserContext(&aThread->iNThread, &regSet, flags);
hgs
parents:
diff changeset
  2629
hgs
parents:
diff changeset
  2630
	//set lengths of output descriptors to 0 prior to filling
hgs
parents:
diff changeset
  2631
	aRegisterFlags.SetLength(0);
hgs
parents:
diff changeset
  2632
hgs
parents:
diff changeset
  2633
	//pointer to first kernel register
hgs
parents:
diff changeset
  2634
	TArmReg *regPtr = &regSet.iR0;
hgs
parents:
diff changeset
  2635
hgs
parents:
diff changeset
  2636
	if (!regPtr)
hgs
parents:
diff changeset
  2637
		return KErrGeneral;
hgs
parents:
diff changeset
  2638
hgs
parents:
diff changeset
  2639
	//calculate number of registers
hgs
parents:
diff changeset
  2640
	TUint numberOfRegisters = aRegisterIds.Length() / sizeof(TRegisterInfo);
hgs
parents:
diff changeset
  2641
hgs
parents:
diff changeset
  2642
	//iterate through registers setting the relevant aRegisterFlags value and
hgs
parents:
diff changeset
  2643
	//setting the necessary value in regSet ready to write to kernel
hgs
parents:
diff changeset
  2644
	for(TUint i=0, offset = 0; i<numberOfRegisters; i++)
hgs
parents:
diff changeset
  2645
		{
hgs
parents:
diff changeset
  2646
		//get current register id
hgs
parents:
diff changeset
  2647
		TRegisterInfo reg;
hgs
parents:
diff changeset
  2648
		TInt err = GetTRegisterInfo(aRegisterIds, i, reg);
hgs
parents:
diff changeset
  2649
		//exit with the error value if there was an error
hgs
parents:
diff changeset
  2650
		if(err != KErrNone)
hgs
parents:
diff changeset
  2651
			{
hgs
parents:
diff changeset
  2652
			return err;
hgs
parents:
diff changeset
  2653
			}
hgs
parents:
diff changeset
  2654
hgs
parents:
diff changeset
  2655
		//if unknown register then exit as can't know how many bytes this entry will
hgs
parents:
diff changeset
  2656
		//represent in aRegisterValues
hgs
parents:
diff changeset
  2657
		TTag registerTag;
hgs
parents:
diff changeset
  2658
		TDebugFunctionality::GetRegister(reg, registerTag);
hgs
parents:
diff changeset
  2659
		if(registerTag.iValue == EAccessUnknown)
hgs
parents:
diff changeset
  2660
			{
hgs
parents:
diff changeset
  2661
			return KErrArgument;
hgs
parents:
diff changeset
  2662
			}
hgs
parents:
diff changeset
  2663
hgs
parents:
diff changeset
  2664
		//get the current register id as a kernel register
hgs
parents:
diff changeset
  2665
		TArmReg armReg;
hgs
parents:
diff changeset
  2666
		err = GetKernelRegisterId(reg, armReg);
hgs
parents:
diff changeset
  2667
		if((err == KErrNotSupported) || (registerTag.iValue == EAccessNone) || (registerTag.iValue == EAccessReadOnly))
hgs
parents:
diff changeset
  2668
			{
hgs
parents:
diff changeset
  2669
			//writing to this register is not supported
hgs
parents:
diff changeset
  2670
			aRegisterFlags.Append(ENotSupported);
hgs
parents:
diff changeset
  2671
			}
hgs
parents:
diff changeset
  2672
		else if(GetFlagAtOffset(flags, armReg))
hgs
parents:
diff changeset
  2673
			{
hgs
parents:
diff changeset
  2674
			if(registerTag.iSize == sizeof(TArmReg))
hgs
parents:
diff changeset
  2675
				{
hgs
parents:
diff changeset
  2676
				//set flag as valid
hgs
parents:
diff changeset
  2677
				aRegisterFlags.Append(EValid);
hgs
parents:
diff changeset
  2678
				if(offset + sizeof(TArmReg) > aRegisterValues.Length())
hgs
parents:
diff changeset
  2679
					{
hgs
parents:
diff changeset
  2680
					//getting this value would cause overflow so exit
hgs
parents:
diff changeset
  2681
					return KErrArgument;
hgs
parents:
diff changeset
  2682
					}
hgs
parents:
diff changeset
  2683
				//write value into register into regSet
hgs
parents:
diff changeset
  2684
				regPtr[armReg] = *(TUint32 *)&aRegisterValues[offset];
hgs
parents:
diff changeset
  2685
				}
hgs
parents:
diff changeset
  2686
			else
hgs
parents:
diff changeset
  2687
				{
hgs
parents:
diff changeset
  2688
				//currently all kernel supported registers are 4 bytes so
hgs
parents:
diff changeset
  2689
				//return EBadSize. Would need updating if/when other register
hgs
parents:
diff changeset
  2690
				//value sizes are supported
hgs
parents:
diff changeset
  2691
				aRegisterFlags.Append(EBadSize);
hgs
parents:
diff changeset
  2692
				}
hgs
parents:
diff changeset
  2693
hgs
parents:
diff changeset
  2694
			}
hgs
parents:
diff changeset
  2695
		else
hgs
parents:
diff changeset
  2696
			{
hgs
parents:
diff changeset
  2697
			//set flag as invalid as register value couldn't be read
hgs
parents:
diff changeset
  2698
			aRegisterFlags.Append(EInValid);
hgs
parents:
diff changeset
  2699
			}
hgs
parents:
diff changeset
  2700
		offset+=registerTag.iSize;
hgs
parents:
diff changeset
  2701
		}
hgs
parents:
diff changeset
  2702
hgs
parents:
diff changeset
  2703
	//write the input data into the registers
hgs
parents:
diff changeset
  2704
	NKern::ThreadSetUserContext(&aThread->iNThread, &regSet);
hgs
parents:
diff changeset
  2705
hgs
parents:
diff changeset
  2706
	//return normally
hgs
parents:
diff changeset
  2707
	return KErrNone;
hgs
parents:
diff changeset
  2708
	}
hgs
parents:
diff changeset
  2709
hgs
parents:
diff changeset
  2710
//
hgs
parents:
diff changeset
  2711
// DRM_DebugChannel::DoSecurityCheck
hgs
parents:
diff changeset
  2712
//
hgs
parents:
diff changeset
  2713
TBool DRM_DebugChannel::DoSecurityCheck()
hgs
parents:
diff changeset
  2714
	{
hgs
parents:
diff changeset
  2715
	LOG_MSG("DRM_DebugChannel::DoSecurityCheck");
hgs
parents:
diff changeset
  2716
	DProcess* clientProcess = iClientThread->iOwningProcess;
hgs
parents:
diff changeset
  2717
	if (clientProcess)
hgs
parents:
diff changeset
  2718
		{
hgs
parents:
diff changeset
  2719
		SSecurityInfo secureInfo = clientProcess->iS;
hgs
parents:
diff changeset
  2720
hgs
parents:
diff changeset
  2721
		LOG_MSG2("DoSecurityCheck - client secure id is 0x%08x",secureInfo.iSecureId);
hgs
parents:
diff changeset
  2722
hgs
parents:
diff changeset
  2723
		// Ensure we really are communicating with the Debug Security Server
hgs
parents:
diff changeset
  2724
		if (secureInfo.iSecureId == KUidDebugSecurityServer.iUid )
hgs
parents:
diff changeset
  2725
			{
hgs
parents:
diff changeset
  2726
			return ETrue;
hgs
parents:
diff changeset
  2727
			}
hgs
parents:
diff changeset
  2728
		}
hgs
parents:
diff changeset
  2729
	return EFalse;
hgs
parents:
diff changeset
  2730
	}
hgs
parents:
diff changeset
  2731
hgs
parents:
diff changeset
  2732
/**
hgs
parents:
diff changeset
  2733
Attempt to read memory from aThread's address space
hgs
parents:
diff changeset
  2734
hgs
parents:
diff changeset
  2735
@param aThread thread from whose address space memory is to be read
hgs
parents:
diff changeset
  2736
@param aSrc pointer to memory location to read memory from
hgs
parents:
diff changeset
  2737
@param aDest pointer to memory location to write memory to
hgs
parents:
diff changeset
  2738
@param aLength number of bytes of data to read
hgs
parents:
diff changeset
  2739
hgs
parents:
diff changeset
  2740
@return KErrNone if memory read successfully,
hgs
parents:
diff changeset
  2741
	or another of the system wide error codes
hgs
parents:
diff changeset
  2742
*/
hgs
parents:
diff changeset
  2743
TInt DRM_DebugChannel::TryToReadMemory(const DThread *aThread, const TAny *aSrc, TAny *aDest, const TUint32 aLength) const
hgs
parents:
diff changeset
  2744
	{
hgs
parents:
diff changeset
  2745
	LOG_MSG("DRM_DebugChannel::TryToReadMemory()");
hgs
parents:
diff changeset
  2746
hgs
parents:
diff changeset
  2747
	// make sure the parameters are valid
hgs
parents:
diff changeset
  2748
	if (!aThread)
hgs
parents:
diff changeset
  2749
		return KErrArgument;
hgs
parents:
diff changeset
  2750
hgs
parents:
diff changeset
  2751
	//Need to revisit this to determine whether there is a way to validate this
hgs
parents:
diff changeset
  2752
#if 0
hgs
parents:
diff changeset
  2753
	//check that the thread is suspended before reading the memory
hgs
parents:
diff changeset
  2754
	if ( !CheckSuspended(aThread) )
hgs
parents:
diff changeset
  2755
		{
hgs
parents:
diff changeset
  2756
		LOG_MSG2("DRM_DebugChannel::TryToReadMemory() thread with id 0x%08x is not suspended", aThread->iId);
hgs
parents:
diff changeset
  2757
		return KErrInUse;
hgs
parents:
diff changeset
  2758
		}
hgs
parents:
diff changeset
  2759
#endif
hgs
parents:
diff changeset
  2760
hgs
parents:
diff changeset
  2761
	LOG_MSG2("Using Kern::ThreadRawRead to read memory at address %x", aSrc);
hgs
parents:
diff changeset
  2762
	return Kern::ThreadRawRead((DThread *)aThread, aSrc, aDest, aLength);
hgs
parents:
diff changeset
  2763
	}
hgs
parents:
diff changeset
  2764
hgs
parents:
diff changeset
  2765
/**
hgs
parents:
diff changeset
  2766
Attempt to write memory to aThread's address space
hgs
parents:
diff changeset
  2767
hgs
parents:
diff changeset
  2768
@param aThread thread to whose address space memory is to be written
hgs
parents:
diff changeset
  2769
@param aDest pointer to memory location to write memory to
hgs
parents:
diff changeset
  2770
@param aSrc pointer to memory location to read memory from
hgs
parents:
diff changeset
  2771
@param aLength number of bytes of data to write
hgs
parents:
diff changeset
  2772
hgs
parents:
diff changeset
  2773
@return KErrNone if memory written successfully, or another of the system wide
hgs
parents:
diff changeset
  2774
        error codes
hgs
parents:
diff changeset
  2775
*/
hgs
parents:
diff changeset
  2776
TInt DRM_DebugChannel::TryToWriteMemory(const DThread *aThread, TAny *aDest, const TAny *aSrc, const TUint32 aLength)
hgs
parents:
diff changeset
  2777
	{
hgs
parents:
diff changeset
  2778
	LOG_MSG("DRM_DebugChannel::TryToWriteMemory()");
hgs
parents:
diff changeset
  2779
hgs
parents:
diff changeset
  2780
hgs
parents:
diff changeset
  2781
	LOG_MSG2("Using Kern::ThreadRawWrite to write memory at address %x", (TUint32)aDest);
hgs
parents:
diff changeset
  2782
	return Kern::ThreadRawWrite((DThread *)aThread, aDest, aSrc, aLength, iClientThread);
hgs
parents:
diff changeset
  2783
	}
hgs
parents:
diff changeset
  2784
hgs
parents:
diff changeset
  2785
/**
hgs
parents:
diff changeset
  2786
@deprecated use DRM_DebugChannel::ReadKernelRegisterValue(DThread *aThread, const TArmReg aKernelRegisterId, T4ByteRegisterValue &aValue) instead
hgs
parents:
diff changeset
  2787
*/
hgs
parents:
diff changeset
  2788
TInt32 DRM_DebugChannel::ReadRegister(DThread *aThread, TInt aNum)
hgs
parents:
diff changeset
  2789
	{
hgs
parents:
diff changeset
  2790
	LOG_MSG("DRM_DebugChannel::ReadRegister()");
hgs
parents:
diff changeset
  2791
hgs
parents:
diff changeset
  2792
	if (!aThread || (aNum < 0) || (aNum >= (TInt16)(sizeof(TArmRegSet)/sizeof(TArmReg))))
hgs
parents:
diff changeset
  2793
		{
hgs
parents:
diff changeset
  2794
		LOG_MSG2("Invalid register number (%d) passed to ReadRegister", aNum);
hgs
parents:
diff changeset
  2795
		return 0;
hgs
parents:
diff changeset
  2796
		}
hgs
parents:
diff changeset
  2797
hgs
parents:
diff changeset
  2798
	TArmRegSet regSet;
hgs
parents:
diff changeset
  2799
	TUint32 unused;
hgs
parents:
diff changeset
  2800
hgs
parents:
diff changeset
  2801
	NKern::ThreadGetUserContext(&aThread->iNThread, &regSet, unused);
hgs
parents:
diff changeset
  2802
hgs
parents:
diff changeset
  2803
	TArmReg *reg = &regSet.iR0;
hgs
parents:
diff changeset
  2804
hgs
parents:
diff changeset
  2805
	return ((TUint32 *)reg)[aNum];
hgs
parents:
diff changeset
  2806
	}
hgs
parents:
diff changeset
  2807
hgs
parents:
diff changeset
  2808
/**
hgs
parents:
diff changeset
  2809
Given a TArmReg register ID, read the value of the register. The register value
hgs
parents:
diff changeset
  2810
will be stored in aValue if the register could be read.
hgs
parents:
diff changeset
  2811
hgs
parents:
diff changeset
  2812
@param aThread thread to read register from
hgs
parents:
diff changeset
  2813
@param aKernelRegisterId ID of register to read from
hgs
parents:
diff changeset
  2814
@param aValue value read from register
hgs
parents:
diff changeset
  2815
hgs
parents:
diff changeset
  2816
@return KErrNone if value was successfully stored in aValue,
hgs
parents:
diff changeset
  2817
        KErrNotSupported if aKernelRegister is not supported by the debug
hgs
parents:
diff changeset
  2818
	security server,
hgs
parents:
diff changeset
  2819
        or a return value from DRM_DebugChannel::ReadDebugRegisterValue()
hgs
parents:
diff changeset
  2820
*/
hgs
parents:
diff changeset
  2821
TInt32 DRM_DebugChannel::ReadKernelRegisterValue(DThread *aThread, const TArmReg aKernelRegisterId, T4ByteRegisterValue &aValue) const
hgs
parents:
diff changeset
  2822
	{
hgs
parents:
diff changeset
  2823
	//get register ID as a TRegisterInfo ID
hgs
parents:
diff changeset
  2824
	TRegisterInfo regId;
hgs
parents:
diff changeset
  2825
	TInt err = GetDebugRegisterId(aKernelRegisterId, regId);
hgs
parents:
diff changeset
  2826
	if(err != KErrNone)
hgs
parents:
diff changeset
  2827
		return err;
hgs
parents:
diff changeset
  2828
hgs
parents:
diff changeset
  2829
	//get the value for the register
hgs
parents:
diff changeset
  2830
	err = ReadDebugRegisterValue(aThread, regId, aValue);
hgs
parents:
diff changeset
  2831
	return err;
hgs
parents:
diff changeset
  2832
	}
hgs
parents:
diff changeset
  2833
hgs
parents:
diff changeset
  2834
/**
hgs
parents:
diff changeset
  2835
Given a TRegisterInfo register ID, read the value of this register. The
hgs
parents:
diff changeset
  2836
register value will be stored in aValue if the register could be read.
hgs
parents:
diff changeset
  2837
hgs
parents:
diff changeset
  2838
@param aThread thread to read register from
hgs
parents:
diff changeset
  2839
@param aDebugRegisterId ID of register to read from
hgs
parents:
diff changeset
  2840
@param aValue value read from register
hgs
parents:
diff changeset
  2841
hgs
parents:
diff changeset
  2842
@return KErrNone if value was successfully stored in aValue,
hgs
parents:
diff changeset
  2843
        TRegisterFlag::EInValid if value could not be read from the register,
hgs
parents:
diff changeset
  2844
        TRegisterFlag::ENotSupported if the register is not supported,
hgs
parents:
diff changeset
  2845
        KErrNoMemory if temporary memory could not be allocated,
hgs
parents:
diff changeset
  2846
        or a return value from DRM_DebugChannel::DoReadRegisters
hgs
parents:
diff changeset
  2847
*/
hgs
parents:
diff changeset
  2848
TInt32 DRM_DebugChannel::ReadDebugRegisterValue(DThread *aThread, const TRegisterInfo aDebugRegisterId, T4ByteRegisterValue &aValue) const
hgs
parents:
diff changeset
  2849
	{
hgs
parents:
diff changeset
  2850
	//allocate temporary buffers to store data
hgs
parents:
diff changeset
  2851
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  2852
	TUint8* id = (TUint8*)Kern::Alloc(sizeof(TRegisterInfo));
hgs
parents:
diff changeset
  2853
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  2854
	if(id == NULL)
hgs
parents:
diff changeset
  2855
		{
hgs
parents:
diff changeset
  2856
		return KErrNoMemory;
hgs
parents:
diff changeset
  2857
		}
hgs
parents:
diff changeset
  2858
hgs
parents:
diff changeset
  2859
	TPtr8 idPtr(id, sizeof(TRegisterInfo));
hgs
parents:
diff changeset
  2860
hgs
parents:
diff changeset
  2861
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  2862
	TUint8* value = (TUint8*)Kern::Alloc(sizeof(T4ByteRegisterValue));
hgs
parents:
diff changeset
  2863
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  2864
	if(value == NULL)
hgs
parents:
diff changeset
  2865
		{
hgs
parents:
diff changeset
  2866
		return KErrNoMemory;
hgs
parents:
diff changeset
  2867
		}
hgs
parents:
diff changeset
  2868
	TPtr8 valuePtr(value, sizeof(T4ByteRegisterValue));
hgs
parents:
diff changeset
  2869
hgs
parents:
diff changeset
  2870
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  2871
	TUint8* flag = (TUint8*)Kern::Alloc(sizeof(TUint8));
hgs
parents:
diff changeset
  2872
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  2873
	if(flag == NULL)
hgs
parents:
diff changeset
  2874
		{
hgs
parents:
diff changeset
  2875
		return KErrNoMemory;
hgs
parents:
diff changeset
  2876
		}
hgs
parents:
diff changeset
  2877
	TPtr8 flagPtr(flag, sizeof(TUint8));
hgs
parents:
diff changeset
  2878
hgs
parents:
diff changeset
  2879
	//store register id in buffer
hgs
parents:
diff changeset
  2880
	idPtr.Append((TUint8*)&aDebugRegisterId, sizeof(TRegisterInfo));
hgs
parents:
diff changeset
  2881
hgs
parents:
diff changeset
  2882
	//read registers
hgs
parents:
diff changeset
  2883
	TInt err = DoReadRegisters(aThread, idPtr, valuePtr, flagPtr);
hgs
parents:
diff changeset
  2884
	if(err == KErrNone)
hgs
parents:
diff changeset
  2885
		{
hgs
parents:
diff changeset
  2886
		if(*flag == EValid)
hgs
parents:
diff changeset
  2887
			{
hgs
parents:
diff changeset
  2888
			//register could be read so store value
hgs
parents:
diff changeset
  2889
			aValue = *(T4ByteRegisterValue*)value;
hgs
parents:
diff changeset
  2890
			}
hgs
parents:
diff changeset
  2891
		else
hgs
parents:
diff changeset
  2892
			{
hgs
parents:
diff changeset
  2893
			//register couldn't be read for some reason
hgs
parents:
diff changeset
  2894
			err = *flag;
hgs
parents:
diff changeset
  2895
			}
hgs
parents:
diff changeset
  2896
		}
hgs
parents:
diff changeset
  2897
hgs
parents:
diff changeset
  2898
	//free memory
hgs
parents:
diff changeset
  2899
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  2900
	Kern::Free(id);
hgs
parents:
diff changeset
  2901
	Kern::Free(value);
hgs
parents:
diff changeset
  2902
	Kern::Free(flag);
hgs
parents:
diff changeset
  2903
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  2904
hgs
parents:
diff changeset
  2905
	return err;
hgs
parents:
diff changeset
  2906
	}
hgs
parents:
diff changeset
  2907
hgs
parents:
diff changeset
  2908
//
hgs
parents:
diff changeset
  2909
// DRM_DebugChannel::NotifyAgentsFromEventPid
hgs
parents:
diff changeset
  2910
//
hgs
parents:
diff changeset
  2911
TBool DRM_DebugChannel::NotifyAgentsFromEventPid(const TDriverEventInfo& aEventInfo)
hgs
parents:
diff changeset
  2912
	{
hgs
parents:
diff changeset
  2913
hgs
parents:
diff changeset
  2914
	// Look for the relevant DTargetProcess
hgs
parents:
diff changeset
  2915
	// We can find out the relevant process id from aEventInfo
hgs
parents:
diff changeset
  2916
	TUint32 pid = aEventInfo.iProcessId;
hgs
parents:
diff changeset
  2917
hgs
parents:
diff changeset
  2918
#ifdef	_DEBUG
hgs
parents:
diff changeset
  2919
	if (aEventInfo.iEventType != EEventsUserTrace)
hgs
parents:
diff changeset
  2920
		{
hgs
parents:
diff changeset
  2921
		LOG_MSG3(" NotifyAgentsFromEventPid - pid = 0x%x, evType=%d", pid, aEventInfo.iEventType);
hgs
parents:
diff changeset
  2922
		}
hgs
parents:
diff changeset
  2923
#endif
hgs
parents:
diff changeset
  2924
hgs
parents:
diff changeset
  2925
	//opening handle to process
hgs
parents:
diff changeset
  2926
	DProcess* targetProcess = DebugUtils::OpenProcessHandle(pid);
hgs
parents:
diff changeset
  2927
hgs
parents:
diff changeset
  2928
	if(!targetProcess)
hgs
parents:
diff changeset
  2929
		{
hgs
parents:
diff changeset
  2930
		LOG_EVENT_MSG("process does not exist!");
hgs
parents:
diff changeset
  2931
		return EFalse;
hgs
parents:
diff changeset
  2932
		}
hgs
parents:
diff changeset
  2933
hgs
parents:
diff changeset
  2934
	// Are we debugging this process - decide based on iFileName
hgs
parents:
diff changeset
  2935
	DCodeSeg* p = targetProcess->iCodeSeg;
hgs
parents:
diff changeset
  2936
	DTargetProcess* foundProcess;
hgs
parents:
diff changeset
  2937
	if (p)
hgs
parents:
diff changeset
  2938
		{
hgs
parents:
diff changeset
  2939
		foundProcess = TheDProcessTracker.FindProcess(*(p->iFileName));
hgs
parents:
diff changeset
  2940
		}
hgs
parents:
diff changeset
  2941
	else
hgs
parents:
diff changeset
  2942
		{
hgs
parents:
diff changeset
  2943
		// special case: may not have a code seg in some cases. in which case we tell everyone!
hgs
parents:
diff changeset
  2944
		if (targetProcess->iName)
hgs
parents:
diff changeset
  2945
			{
hgs
parents:
diff changeset
  2946
			// copy the name of the process
hgs
parents:
diff changeset
  2947
			foundProcess = TheDProcessTracker.FindProcess(*(targetProcess->iName));
hgs
parents:
diff changeset
  2948
			}
hgs
parents:
diff changeset
  2949
		else
hgs
parents:
diff changeset
  2950
			{
hgs
parents:
diff changeset
  2951
			foundProcess = NULL;
hgs
parents:
diff changeset
  2952
			}
hgs
parents:
diff changeset
  2953
		}
hgs
parents:
diff changeset
  2954
hgs
parents:
diff changeset
  2955
    //close the handle
hgs
parents:
diff changeset
  2956
    targetProcess->Close(NULL);
hgs
parents:
diff changeset
  2957
hgs
parents:
diff changeset
  2958
	if (foundProcess)
hgs
parents:
diff changeset
  2959
		{
hgs
parents:
diff changeset
  2960
		foundProcess->NotifyEvent(aEventInfo);
hgs
parents:
diff changeset
  2961
		return ETrue;
hgs
parents:
diff changeset
  2962
		}
hgs
parents:
diff changeset
  2963
	else
hgs
parents:
diff changeset
  2964
		{
hgs
parents:
diff changeset
  2965
		// Check if there's an attach-to-all handler
hgs
parents:
diff changeset
  2966
		DDebugAgent* agent = TheDProcessTracker.GetCurrentAgentAttachedToAll();
hgs
parents:
diff changeset
  2967
		if (agent)
hgs
parents:
diff changeset
  2968
			{
hgs
parents:
diff changeset
  2969
			LOG_EVENT_MSG2(" NotifyAgentsFromEventPid - found attach all agent 0x%lx", agent->Id());
hgs
parents:
diff changeset
  2970
			agent->NotifyEvent(aEventInfo);
hgs
parents:
diff changeset
  2971
			return ETrue;
hgs
parents:
diff changeset
  2972
			}
hgs
parents:
diff changeset
  2973
		}
hgs
parents:
diff changeset
  2974
hgs
parents:
diff changeset
  2975
	// we are not debugging this process
hgs
parents:
diff changeset
  2976
	return EFalse;
hgs
parents:
diff changeset
  2977
	}
hgs
parents:
diff changeset
  2978
hgs
parents:
diff changeset
  2979
DECLARE_STANDARD_LDD()
hgs
parents:
diff changeset
  2980
	{
hgs
parents:
diff changeset
  2981
	return new DRM_DebugDriverFactory;
hgs
parents:
diff changeset
  2982
	}
hgs
parents:
diff changeset
  2983
hgs
parents:
diff changeset
  2984
/**
hgs
parents:
diff changeset
  2985
Helper function
hgs
parents:
diff changeset
  2986
hgs
parents:
diff changeset
  2987
Allocates memory in current thread with a max length the same as aSrcDes. If
hgs
parents:
diff changeset
  2988
aReadFromClient is true (as it is by default) then the data from aSrdDes is
hgs
parents:
diff changeset
  2989
copied into the allocated aDestDes buffer.
hgs
parents:
diff changeset
  2990
hgs
parents:
diff changeset
  2991
Use of this function should be followed at a later time by a call such as
hgs
parents:
diff changeset
  2992
Kern::Free(aDestDes.Ptr())
hgs
parents:
diff changeset
  2993
hgs
parents:
diff changeset
  2994
@param aThread pointer to thread to read data from
hgs
parents:
diff changeset
  2995
@param aSrcDes descriptor in aThread to read data from
hgs
parents:
diff changeset
  2996
@param aDestDes location to read data to. Memory is allocated at this location,
hgs
parents:
diff changeset
  2997
       if memory is already allocated at this location then the function will
hgs
parents:
diff changeset
  2998
       return KErrArgument
hgs
parents:
diff changeset
  2999
@param aReadFromClient if false then data is not actually read from the
hgs
parents:
diff changeset
  3000
       client, the memory is simply allocated
hgs
parents:
diff changeset
  3001
@param aOffest offset into aSrcDes to start reading from. Default is 0.
hgs
parents:
diff changeset
  3002
hgs
parents:
diff changeset
  3003
@return KErrNone if there were no problems,
hgs
parents:
diff changeset
  3004
        KErrArgument if aDestDes.Ptr() != NULL or aSrcDes has max length 0,
hgs
parents:
diff changeset
  3005
        KErrNoMemory if could not allocate memory,
hgs
parents:
diff changeset
  3006
        or one of the other system wide error codes
hgs
parents:
diff changeset
  3007
*/
hgs
parents:
diff changeset
  3008
TInt DRM_DebugChannel::AllocAndReadDes(DThread *aThread, const TDesC8& aSrcDes, TPtr8& aDestDes, const TBool aReadFromClient, const TUint aOffset) const
hgs
parents:
diff changeset
  3009
	{
hgs
parents:
diff changeset
  3010
hgs
parents:
diff changeset
  3011
	//check thread is not null
hgs
parents:
diff changeset
  3012
	if(!aThread)
hgs
parents:
diff changeset
  3013
		{
hgs
parents:
diff changeset
  3014
		return KErrArgument;
hgs
parents:
diff changeset
  3015
		}
hgs
parents:
diff changeset
  3016
hgs
parents:
diff changeset
  3017
	//check aDestDes is empty
hgs
parents:
diff changeset
  3018
	if(aDestDes.Ptr() != NULL)
hgs
parents:
diff changeset
  3019
		{
hgs
parents:
diff changeset
  3020
		return KErrArgument;
hgs
parents:
diff changeset
  3021
		}
hgs
parents:
diff changeset
  3022
hgs
parents:
diff changeset
  3023
	//get the source descriptor's max length and exit if 0
hgs
parents:
diff changeset
  3024
	TUint srcMaxLength = Kern::ThreadGetDesMaxLength(aThread, &aSrcDes);
hgs
parents:
diff changeset
  3025
	if(srcMaxLength == 0)
hgs
parents:
diff changeset
  3026
		{
hgs
parents:
diff changeset
  3027
		return KErrNone;
hgs
parents:
diff changeset
  3028
		}
hgs
parents:
diff changeset
  3029
hgs
parents:
diff changeset
  3030
	//allocate memory and return if none available
hgs
parents:
diff changeset
  3031
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  3032
	TUint8 *destPtr = (TUint8*)Kern::Alloc(srcMaxLength);
hgs
parents:
diff changeset
  3033
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  3034
	if (!destPtr)
hgs
parents:
diff changeset
  3035
		{
hgs
parents:
diff changeset
  3036
		return KErrNoMemory;
hgs
parents:
diff changeset
  3037
		}
hgs
parents:
diff changeset
  3038
hgs
parents:
diff changeset
  3039
	//point the TPtr8 at the target memory
hgs
parents:
diff changeset
  3040
	aDestDes.Set(destPtr, srcMaxLength, srcMaxLength);
hgs
parents:
diff changeset
  3041
hgs
parents:
diff changeset
  3042
	if(aReadFromClient)
hgs
parents:
diff changeset
  3043
		{
hgs
parents:
diff changeset
  3044
		//read data from the client thread and return status code
hgs
parents:
diff changeset
  3045
		return Kern::ThreadDesRead(aThread, &aSrcDes, aDestDes, aOffset);
hgs
parents:
diff changeset
  3046
		}
hgs
parents:
diff changeset
  3047
	else
hgs
parents:
diff changeset
  3048
		{
hgs
parents:
diff changeset
  3049
		return KErrNone;
hgs
parents:
diff changeset
  3050
		}
hgs
parents:
diff changeset
  3051
	}
hgs
parents:
diff changeset
  3052
hgs
parents:
diff changeset
  3053
/**
hgs
parents:
diff changeset
  3054
Helper function to extract a TRegisterInfo value from a descriptor containing
hgs
parents:
diff changeset
  3055
binary data.
hgs
parents:
diff changeset
  3056
hgs
parents:
diff changeset
  3057
@param aRegisterIds descriptor containing register IDs
hgs
parents:
diff changeset
  3058
@param aOffset offset in bytes into the descriptor to start reading data from.
hgs
parents:
diff changeset
  3059
       If this value is not a multiple of sizeof(TRegisterInfo) then a
hgs
parents:
diff changeset
  3060
       KErrArgument error is returned.
hgs
parents:
diff changeset
  3061
@param aValue will contain the returned value
hgs
parents:
diff changeset
  3062
hgs
parents:
diff changeset
  3063
@return KErrNone if aValue was set correctly, KErrArgument if bad arguments
hgs
parents:
diff changeset
  3064
        were passed in
hgs
parents:
diff changeset
  3065
*/
hgs
parents:
diff changeset
  3066
TInt DRM_DebugChannel::GetTRegisterInfo(const TDesC8 &aRegisterIds, const TUint aIndex, TRegisterInfo &aValue) const
hgs
parents:
diff changeset
  3067
	{
hgs
parents:
diff changeset
  3068
	TUint length = aRegisterIds.Length();
hgs
parents:
diff changeset
  3069
hgs
parents:
diff changeset
  3070
	TUint size = sizeof(TRegisterInfo);
hgs
parents:
diff changeset
  3071
hgs
parents:
diff changeset
  3072
	//check that not trying to read past end of descriptor
hgs
parents:
diff changeset
  3073
	if((aIndex + 1) * size > length)
hgs
parents:
diff changeset
  3074
		return KErrArgument;
hgs
parents:
diff changeset
  3075
hgs
parents:
diff changeset
  3076
	//get pointer to descriptor's data
hgs
parents:
diff changeset
  3077
	const TUint8 *dataPtr = aRegisterIds.Ptr();
hgs
parents:
diff changeset
  3078
	const TRegisterInfo *registerId = reinterpret_cast<const TRegisterInfo*>(dataPtr + (aIndex * size));
hgs
parents:
diff changeset
  3079
hgs
parents:
diff changeset
  3080
	aValue = *registerId;
hgs
parents:
diff changeset
  3081
hgs
parents:
diff changeset
  3082
	return KErrNone;
hgs
parents:
diff changeset
  3083
	}
hgs
parents:
diff changeset
  3084
hgs
parents:
diff changeset
  3085
/**
hgs
parents:
diff changeset
  3086
Helper function to get the kernel register ID of the TRegisterInfo defined register.
hgs
parents:
diff changeset
  3087
hgs
parents:
diff changeset
  3088
@param aDebugRegister the debug register ID to return the kernel ID for
hgs
parents:
diff changeset
  3089
@param aKernelRegister corresponding value of register aDebugRegister
hgs
parents:
diff changeset
  3090
hgs
parents:
diff changeset
  3091
@return KErrNone if translation occurred without problems
hgs
parents:
diff changeset
  3092
        KErrNotSupported if aDebugRegister is not supported by the kernel
hgs
parents:
diff changeset
  3093
*/
hgs
parents:
diff changeset
  3094
TInt DRM_DebugChannel::GetKernelRegisterId(const TRegisterInfo aDebugRegister, TArmReg& aKernelRegister) const
hgs
parents:
diff changeset
  3095
	{
hgs
parents:
diff changeset
  3096
	if(Register::IsCoreReg(aDebugRegister))
hgs
parents:
diff changeset
  3097
		{
hgs
parents:
diff changeset
  3098
		TUint id = Register::GetCoreRegId(aDebugRegister);
hgs
parents:
diff changeset
  3099
		//first 17 registers match the first 17 kernel registers
hgs
parents:
diff changeset
  3100
		if(id < 17)
hgs
parents:
diff changeset
  3101
			{
hgs
parents:
diff changeset
  3102
			aKernelRegister = id;
hgs
parents:
diff changeset
  3103
			}
hgs
parents:
diff changeset
  3104
		else
hgs
parents:
diff changeset
  3105
			{
hgs
parents:
diff changeset
  3106
			return KErrNotSupported;
hgs
parents:
diff changeset
  3107
			}
hgs
parents:
diff changeset
  3108
		}
hgs
parents:
diff changeset
  3109
	else if(Register::IsCoproReg(aDebugRegister))
hgs
parents:
diff changeset
  3110
		{
hgs
parents:
diff changeset
  3111
		TUint32 crn = Register::GetCRn(aDebugRegister);
hgs
parents:
diff changeset
  3112
		TUint32 crm = Register::GetCRm(aDebugRegister);
hgs
parents:
diff changeset
  3113
		TUint32 opcode1 = Register::GetOpcode1(aDebugRegister);
hgs
parents:
diff changeset
  3114
		TUint32 opcode2 = Register::GetOpcode2(aDebugRegister);
hgs
parents:
diff changeset
  3115
		TUint32 coproNum = Register::GetCoproNum(aDebugRegister);
hgs
parents:
diff changeset
  3116
hgs
parents:
diff changeset
  3117
		//each coprocessor register has potentially different characteristics
hgs
parents:
diff changeset
  3118
		//so need to identify each individually
hgs
parents:
diff changeset
  3119
hgs
parents:
diff changeset
  3120
		//this is the DACR, the ARM ARM specifies that the CRn and the
hgs
parents:
diff changeset
  3121
		//Opcodes are not relevant, section B3-24, point 3.7.3
hgs
parents:
diff changeset
  3122
		if((coproNum == 15) && (crm == 3))
hgs
parents:
diff changeset
  3123
			{
hgs
parents:
diff changeset
  3124
			aKernelRegister = EArmDacr;
hgs
parents:
diff changeset
  3125
			}
hgs
parents:
diff changeset
  3126
		else
hgs
parents:
diff changeset
  3127
			{
hgs
parents:
diff changeset
  3128
			return KErrNotSupported;
hgs
parents:
diff changeset
  3129
			}
hgs
parents:
diff changeset
  3130
		}
hgs
parents:
diff changeset
  3131
	else // might be supported at a later date
hgs
parents:
diff changeset
  3132
		{
hgs
parents:
diff changeset
  3133
		return KErrNotSupported;
hgs
parents:
diff changeset
  3134
		}
hgs
parents:
diff changeset
  3135
hgs
parents:
diff changeset
  3136
	return KErrNone;
hgs
parents:
diff changeset
  3137
	}
hgs
parents:
diff changeset
  3138
hgs
parents:
diff changeset
  3139
/**
hgs
parents:
diff changeset
  3140
Helper function to get the debug register ID of the kernel defined register.
hgs
parents:
diff changeset
  3141
hgs
parents:
diff changeset
  3142
@param aKernelRegister the kernel register ID to return the debug ID for
hgs
parents:
diff changeset
  3143
@param aDebugRegister corresponding value of register aKernelRegister
hgs
parents:
diff changeset
  3144
hgs
parents:
diff changeset
  3145
@return KErrNone if translation occured without problems
hgs
parents:
diff changeset
  3146
        KErrNotSupported if aKernelRegister is not supported by the debug
hgs
parents:
diff changeset
  3147
	security server
hgs
parents:
diff changeset
  3148
*/
hgs
parents:
diff changeset
  3149
TInt DRM_DebugChannel::GetDebugRegisterId(const TArmReg aKernelRegister, TRegisterInfo &aDebugRegister) const
hgs
parents:
diff changeset
  3150
	{
hgs
parents:
diff changeset
  3151
hgs
parents:
diff changeset
  3152
	// registers 0 - 15 and the CPSR share the same values as with the debug enums
hgs
parents:
diff changeset
  3153
	if(aKernelRegister < 17)
hgs
parents:
diff changeset
  3154
		{
hgs
parents:
diff changeset
  3155
		TUint32 id = aKernelRegister;
hgs
parents:
diff changeset
  3156
		aDebugRegister = id << 8;
hgs
parents:
diff changeset
  3157
		}
hgs
parents:
diff changeset
  3158
	//the DACR value is special and corresponds to EDF_Register_DACR
hgs
parents:
diff changeset
  3159
	else if(aKernelRegister == EArmDacr)
hgs
parents:
diff changeset
  3160
		{
hgs
parents:
diff changeset
  3161
		aDebugRegister = 0x00300f01;
hgs
parents:
diff changeset
  3162
		}
hgs
parents:
diff changeset
  3163
	// must be an unsupported register, return an error as such
hgs
parents:
diff changeset
  3164
	else
hgs
parents:
diff changeset
  3165
		{
hgs
parents:
diff changeset
  3166
		return KErrNotSupported;
hgs
parents:
diff changeset
  3167
		}
hgs
parents:
diff changeset
  3168
hgs
parents:
diff changeset
  3169
	//found a supported register so return KErrNone
hgs
parents:
diff changeset
  3170
	return KErrNone;
hgs
parents:
diff changeset
  3171
	}
hgs
parents:
diff changeset
  3172
hgs
parents:
diff changeset
  3173
/**
hgs
parents:
diff changeset
  3174
Helper function to find out whether the aIndex flag is set. This is equivalent
hgs
parents:
diff changeset
  3175
to the aIndex bit of aFlags being non-zero.
hgs
parents:
diff changeset
  3176
hgs
parents:
diff changeset
  3177
@param aFlags set of flags
hgs
parents:
diff changeset
  3178
@param aIndex offset into aFlags to get flag from
hgs
parents:
diff changeset
  3179
hgs
parents:
diff changeset
  3180
@return ETrue if bit is set, EFalse if not
hgs
parents:
diff changeset
  3181
*/
hgs
parents:
diff changeset
  3182
TBool DRM_DebugChannel::GetFlagAtOffset(const TUint32 aFlags, const TArmReg aIndex) const
hgs
parents:
diff changeset
  3183
	{
hgs
parents:
diff changeset
  3184
	return aFlags & (1<<aIndex);
hgs
parents:
diff changeset
  3185
	}
hgs
parents:
diff changeset
  3186
hgs
parents:
diff changeset
  3187
/* Register the attachment of a debug agent to a process to be debugged
hgs
parents:
diff changeset
  3188
 *
hgs
parents:
diff changeset
  3189
 * @param a1 - TDes8 target process name
hgs
parents:
diff changeset
  3190
 * @param a2 - &TUint64 - Debug Agent Id
hgs
parents:
diff changeset
  3191
 *
hgs
parents:
diff changeset
  3192
 * @return - KErrNone if successful. KErrArgument if the filepath is not a valid size.
hgs
parents:
diff changeset
  3193
 * KErrOutOfMemory if there is insufficient memory. Or one of the other system wide error codes
hgs
parents:
diff changeset
  3194
 * if appropriate.
hgs
parents:
diff changeset
  3195
 */
hgs
parents:
diff changeset
  3196
TInt DRM_DebugChannel::AttachProcess(TAny* a1, TAny* a2)
hgs
parents:
diff changeset
  3197
	{
hgs
parents:
diff changeset
  3198
	LOG_MSG("DRM_DebugChannel::AttachProcess()");
hgs
parents:
diff changeset
  3199
hgs
parents:
diff changeset
  3200
	// Validate the supplied TDes8 target process name in a1
hgs
parents:
diff changeset
  3201
	TInt length = Kern::ThreadGetDesLength(iClientThread, a1);
hgs
parents:
diff changeset
  3202
	if (length < 0) return length;
hgs
parents:
diff changeset
  3203
hgs
parents:
diff changeset
  3204
	// Check the processname is a valid size for a filepath
hgs
parents:
diff changeset
  3205
	if (length < 1 || length >= KMaxPath)
hgs
parents:
diff changeset
  3206
		{
hgs
parents:
diff changeset
  3207
		return KErrArgument;
hgs
parents:
diff changeset
  3208
		}
hgs
parents:
diff changeset
  3209
hgs
parents:
diff changeset
  3210
	// Allocate space to store the target process name in a kernel-side TPtr8
hgs
parents:
diff changeset
  3211
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  3212
	TUint8* buffer = (TUint8*)Kern::AllocZ(length);
hgs
parents:
diff changeset
  3213
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  3214
	if (buffer==NULL)
hgs
parents:
diff changeset
  3215
		{
hgs
parents:
diff changeset
  3216
		// Out of memory
hgs
parents:
diff changeset
  3217
		return KErrNoMemory;
hgs
parents:
diff changeset
  3218
		}
hgs
parents:
diff changeset
  3219
hgs
parents:
diff changeset
  3220
	// A temporary descriptor to store the target process name
hgs
parents:
diff changeset
  3221
	TPtr8 targetProcessName(buffer,length,length);
hgs
parents:
diff changeset
  3222
hgs
parents:
diff changeset
  3223
	// Read the user-side data into targetProcessName
hgs
parents:
diff changeset
  3224
	TInt err = Kern::ThreadDesRead(iClientThread,a1,targetProcessName,0,KChunkShiftBy0);
hgs
parents:
diff changeset
  3225
	if (err != KErrNone)
hgs
parents:
diff changeset
  3226
		{
hgs
parents:
diff changeset
  3227
		// Could not read the user-side descriptor containing the target process name
hgs
parents:
diff changeset
  3228
		NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  3229
		Kern::Free(buffer);
hgs
parents:
diff changeset
  3230
		NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  3231
hgs
parents:
diff changeset
  3232
		return err;
hgs
parents:
diff changeset
  3233
		}
hgs
parents:
diff changeset
  3234
hgs
parents:
diff changeset
  3235
	// Obtain the Debug Agent Id
hgs
parents:
diff changeset
  3236
	TUint64 debugAgentId = 0;
hgs
parents:
diff changeset
  3237
hgs
parents:
diff changeset
  3238
	err = Kern::ThreadRawRead(iClientThread,a2,&debugAgentId,sizeof(debugAgentId));
hgs
parents:
diff changeset
  3239
	if (err != KErrNone)
hgs
parents:
diff changeset
  3240
		{
hgs
parents:
diff changeset
  3241
		// Something bad happened so free the memory and return
hgs
parents:
diff changeset
  3242
		NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  3243
		Kern::Free(buffer);
hgs
parents:
diff changeset
  3244
		NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  3245
		return err;
hgs
parents:
diff changeset
  3246
		}
hgs
parents:
diff changeset
  3247
hgs
parents:
diff changeset
  3248
	// Add the target process to our list of tracked processes
hgs
parents:
diff changeset
  3249
	err = TheDProcessTracker.AttachProcess(targetProcessName, debugAgentId);
hgs
parents:
diff changeset
  3250
hgs
parents:
diff changeset
  3251
	// Free the kernel-side memory containing targetProcessName data
hgs
parents:
diff changeset
  3252
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  3253
	Kern::Free(buffer);
hgs
parents:
diff changeset
  3254
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  3255
hgs
parents:
diff changeset
  3256
	return err;
hgs
parents:
diff changeset
  3257
	}
hgs
parents:
diff changeset
  3258
hgs
parents:
diff changeset
  3259
/* Register the detachment of a debug agent to a process to be debugged.
hgs
parents:
diff changeset
  3260
 *
hgs
parents:
diff changeset
  3261
 * @param - a1 TDes8 target process name in a1
hgs
parents:
diff changeset
  3262
 * @param a2 - &TUint64 - Debug Agent Id
hgs
parents:
diff changeset
  3263
 *
hgs
parents:
diff changeset
  3264
 * @return - KErrNone if successful. KErrArgument if the filepath is not a valid size.
hgs
parents:
diff changeset
  3265
 * KErrOutOfMemory if there is insufficient memory. Or one of the other system wide error codes
hgs
parents:
diff changeset
  3266
 * if appropriate.
hgs
parents:
diff changeset
  3267
 */
hgs
parents:
diff changeset
  3268
TInt DRM_DebugChannel::DetachProcess(TAny* a1, TAny* a2)
hgs
parents:
diff changeset
  3269
	{
hgs
parents:
diff changeset
  3270
	TInt length = Kern::ThreadGetDesLength(iClientThread, a1);
hgs
parents:
diff changeset
  3271
	if (length < 0)
hgs
parents:
diff changeset
  3272
		{
hgs
parents:
diff changeset
  3273
		return length;
hgs
parents:
diff changeset
  3274
		}
hgs
parents:
diff changeset
  3275
hgs
parents:
diff changeset
  3276
	if (length < 1 || length >= KMaxPath)
hgs
parents:
diff changeset
  3277
		{
hgs
parents:
diff changeset
  3278
		return KErrArgument;
hgs
parents:
diff changeset
  3279
		}
hgs
parents:
diff changeset
  3280
hgs
parents:
diff changeset
  3281
	HBuf* targetProcessName = HBuf::New(length);
hgs
parents:
diff changeset
  3282
	if (targetProcessName == NULL)
hgs
parents:
diff changeset
  3283
		{
hgs
parents:
diff changeset
  3284
		// Out of memory
hgs
parents:
diff changeset
  3285
		return KErrNoMemory;
hgs
parents:
diff changeset
  3286
		}
hgs
parents:
diff changeset
  3287
hgs
parents:
diff changeset
  3288
	// Read the user-side data into buf
hgs
parents:
diff changeset
  3289
	TInt err = Kern::ThreadDesRead(iClientThread,a1,*targetProcessName,0,KChunkShiftBy0);
hgs
parents:
diff changeset
  3290
	if (err != KErrNone)
hgs
parents:
diff changeset
  3291
		{
hgs
parents:
diff changeset
  3292
		// Something bad happened so free the memory and return
hgs
parents:
diff changeset
  3293
		delete targetProcessName;
hgs
parents:
diff changeset
  3294
		return err;
hgs
parents:
diff changeset
  3295
		}
hgs
parents:
diff changeset
  3296
hgs
parents:
diff changeset
  3297
	// Obtain the AgentId
hgs
parents:
diff changeset
  3298
	TUint64 debugAgentId = 0;
hgs
parents:
diff changeset
  3299
hgs
parents:
diff changeset
  3300
	err = Kern::ThreadRawRead(iClientThread,a2,&debugAgentId,sizeof(debugAgentId));
hgs
parents:
diff changeset
  3301
	if (err == KErrNone)
hgs
parents:
diff changeset
  3302
		{
hgs
parents:
diff changeset
  3303
		// Remove the process from our list of tracked processes
hgs
parents:
diff changeset
  3304
		err = TheDProcessTracker.DetachProcess(*targetProcessName, debugAgentId);
hgs
parents:
diff changeset
  3305
		}
hgs
parents:
diff changeset
  3306
hgs
parents:
diff changeset
  3307
	// Free the kernel-side memory containing targetProcessName data
hgs
parents:
diff changeset
  3308
	delete targetProcessName;
hgs
parents:
diff changeset
  3309
	return err;
hgs
parents:
diff changeset
  3310
	}
hgs
parents:
diff changeset
  3311
hgs
parents:
diff changeset
  3312
/* Register the detachment of a debug agent from all processes being debugged.
hgs
parents:
diff changeset
  3313
 *
hgs
parents:
diff changeset
  3314
 * @param - a1 - &TUint64 Debug Agent Id.
hgs
parents:
diff changeset
  3315
 * @return - KErrNone if successful. One of the system-wide error codes otherwise.
hgs
parents:
diff changeset
  3316
 */
hgs
parents:
diff changeset
  3317
TInt DRM_DebugChannel::DetachAgent(TAny* a1, TAny* a2)
hgs
parents:
diff changeset
  3318
	{
hgs
parents:
diff changeset
  3319
	// Obtain the AgentId
hgs
parents:
diff changeset
  3320
	TUint64 debugAgentId = 0;
hgs
parents:
diff changeset
  3321
hgs
parents:
diff changeset
  3322
	TInt err = Kern::ThreadRawRead(iClientThread,a1,&debugAgentId,sizeof(debugAgentId));
hgs
parents:
diff changeset
  3323
	if (err != KErrNone)
hgs
parents:
diff changeset
  3324
		{
hgs
parents:
diff changeset
  3325
		return err;
hgs
parents:
diff changeset
  3326
		}
hgs
parents:
diff changeset
  3327
hgs
parents:
diff changeset
  3328
	// Remove the process from our list of tracked processes
hgs
parents:
diff changeset
  3329
	return TheDProcessTracker.DetachAgent(debugAgentId);
hgs
parents:
diff changeset
  3330
	}
hgs
parents:
diff changeset
  3331
hgs
parents:
diff changeset
  3332
/* Set the action associated with a particular kernel event for a given agent and target process
hgs
parents:
diff changeset
  3333
 *
hgs
parents:
diff changeset
  3334
 * @param - a1 TDes8 target process name in a1
hgs
parents:
diff changeset
  3335
 * @param - a2 &TRM_DebugEventActionInfo
hgs
parents:
diff changeset
  3336
 * @return - KErrNone if successful. KErrArgument if the filepath is an invalid size. Or one of
hgs
parents:
diff changeset
  3337
 * the other system wide error codes if appropriate.
hgs
parents:
diff changeset
  3338
 */
hgs
parents:
diff changeset
  3339
TInt DRM_DebugChannel::SetEventAction(TAny* a1, TAny* a2)
hgs
parents:
diff changeset
  3340
	{
hgs
parents:
diff changeset
  3341
	// Validate the supplied TDes8 target process name in a1
hgs
parents:
diff changeset
  3342
	TInt length, maxLength;
hgs
parents:
diff changeset
  3343
	TUint8* aPtr;
hgs
parents:
diff changeset
  3344
hgs
parents:
diff changeset
  3345
	TInt err = Kern::ThreadGetDesInfo(iClientThread,\
hgs
parents:
diff changeset
  3346
		a1,\
hgs
parents:
diff changeset
  3347
		length,\
hgs
parents:
diff changeset
  3348
		maxLength,\
hgs
parents:
diff changeset
  3349
		aPtr,\
hgs
parents:
diff changeset
  3350
		EFalse);
hgs
parents:
diff changeset
  3351
	if (err != KErrNone)
hgs
parents:
diff changeset
  3352
		{
hgs
parents:
diff changeset
  3353
		return err;
hgs
parents:
diff changeset
  3354
		}
hgs
parents:
diff changeset
  3355
hgs
parents:
diff changeset
  3356
	if (length < 1 || length >= KMaxPath)
hgs
parents:
diff changeset
  3357
		{
hgs
parents:
diff changeset
  3358
		return KErrArgument;
hgs
parents:
diff changeset
  3359
		}
hgs
parents:
diff changeset
  3360
hgs
parents:
diff changeset
  3361
	if (maxLength < 1 || maxLength >= KMaxPath)
hgs
parents:
diff changeset
  3362
		{
hgs
parents:
diff changeset
  3363
		return KErrArgument;
hgs
parents:
diff changeset
  3364
		}
hgs
parents:
diff changeset
  3365
hgs
parents:
diff changeset
  3366
	// Allocate space to store the target process name in a kernelspace TPtr8
hgs
parents:
diff changeset
  3367
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  3368
	TUint8* buffer = (TUint8*)Kern::AllocZ(length);
hgs
parents:
diff changeset
  3369
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  3370
	if (buffer==NULL)
hgs
parents:
diff changeset
  3371
		{
hgs
parents:
diff changeset
  3372
		// Out of memory
hgs
parents:
diff changeset
  3373
		return KErrNoMemory;
hgs
parents:
diff changeset
  3374
		}
hgs
parents:
diff changeset
  3375
	TPtr8 targetProcessName(buffer,length,length);
hgs
parents:
diff changeset
  3376
hgs
parents:
diff changeset
  3377
	// Read the user-side data into targetProcessName
hgs
parents:
diff changeset
  3378
	err = Kern::ThreadDesRead(iClientThread,a1,targetProcessName,0,KChunkShiftBy0);
hgs
parents:
diff changeset
  3379
	if (err != KErrNone)
hgs
parents:
diff changeset
  3380
		{
hgs
parents:
diff changeset
  3381
		// Something bad happened so free the memory and return
hgs
parents:
diff changeset
  3382
		NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  3383
		Kern::Free(buffer);
hgs
parents:
diff changeset
  3384
		NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  3385
hgs
parents:
diff changeset
  3386
		return err;
hgs
parents:
diff changeset
  3387
		}
hgs
parents:
diff changeset
  3388
hgs
parents:
diff changeset
  3389
	// Read the Event and Action from the user-side
hgs
parents:
diff changeset
  3390
	TRM_DebugEventActionInfo info(0,0,0);
hgs
parents:
diff changeset
  3391
hgs
parents:
diff changeset
  3392
	err = Kern::ThreadRawRead(iClientThread, a2, &info, sizeof(info));
hgs
parents:
diff changeset
  3393
	if (err != KErrNone)
hgs
parents:
diff changeset
  3394
		{
hgs
parents:
diff changeset
  3395
		// Could not read event action data from the user-side
hgs
parents:
diff changeset
  3396
hgs
parents:
diff changeset
  3397
		// Free memory used for targetProcessName
hgs
parents:
diff changeset
  3398
		NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  3399
		Kern::Free(buffer);
hgs
parents:
diff changeset
  3400
		NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  3401
hgs
parents:
diff changeset
  3402
		return err;
hgs
parents:
diff changeset
  3403
		}
hgs
parents:
diff changeset
  3404
	
hgs
parents:
diff changeset
  3405
	DDebugAgent* debugAgent = TheDProcessTracker.FindAgentForProcessAndId( targetProcessName, info.iAgentId );
hgs
parents:
diff changeset
  3406
	if (debugAgent != NULL)
hgs
parents:
diff changeset
  3407
		{
hgs
parents:
diff changeset
  3408
		// Set the event action
hgs
parents:
diff changeset
  3409
		err = debugAgent->SetEventAction((TEventType)info.iEvent,(TKernelEventAction)info.iAction);
hgs
parents:
diff changeset
  3410
		}
hgs
parents:
diff changeset
  3411
	else
hgs
parents:
diff changeset
  3412
		{
hgs
parents:
diff changeset
  3413
		// Bad agent means there is no tracking agent
hgs
parents:
diff changeset
  3414
		LOG_MSG2("Cannot locate debug agent with pid 0x%0xlx",info.iAgentId);
hgs
parents:
diff changeset
  3415
		err = KErrNotFound;
hgs
parents:
diff changeset
  3416
		}
hgs
parents:
diff changeset
  3417
hgs
parents:
diff changeset
  3418
	// Free memory used for targetProcessName
hgs
parents:
diff changeset
  3419
	NKern::ThreadEnterCS();
hgs
parents:
diff changeset
  3420
	Kern::Free(buffer);
hgs
parents:
diff changeset
  3421
	NKern::ThreadLeaveCS();
hgs
parents:
diff changeset
  3422
hgs
parents:
diff changeset
  3423
	return err;
hgs
parents:
diff changeset
  3424
hgs
parents:
diff changeset
  3425
	}
hgs
parents:
diff changeset
  3426
hgs
parents:
diff changeset
  3427
TInt DRM_DebugChannel::Step(const TUint32 aThreadId, const TUint32 aNumSteps)
hgs
parents:
diff changeset
  3428
	{
hgs
parents:
diff changeset
  3429
	LOG_MSG3("DRM_DebugChannel::Step(aThreadId = 0x%08x, aNumSteps = 0x%08x)\n",aThreadId,aNumSteps);
hgs
parents:
diff changeset
  3430
hgs
parents:
diff changeset
  3431
	DThread* thread = DebugUtils::OpenThreadHandle(aThreadId);
hgs
parents:
diff changeset
  3432
hgs
parents:
diff changeset
  3433
	if (thread == NULL)
hgs
parents:
diff changeset
  3434
		{
hgs
parents:
diff changeset
  3435
		// The thread terminated before we could open it.
hgs
parents:
diff changeset
  3436
		LOG_MSG2("DRM_DebugChannel::Step - Could not open thread %u", aThreadId);
hgs
parents:
diff changeset
  3437
hgs
parents:
diff changeset
  3438
		return KErrArgument;
hgs
parents:
diff changeset
  3439
		}
hgs
parents:
diff changeset
  3440
hgs
parents:
diff changeset
  3441
	// We simply repeat this for desired number of steps
hgs
parents:
diff changeset
  3442
	TInt err = KErrNone;
hgs
parents:
diff changeset
  3443
hgs
parents:
diff changeset
  3444
	// Need to step from the current location for 'n' steps
hgs
parents:
diff changeset
  3445
	TUint32 startAddress;
hgs
parents:
diff changeset
  3446
hgs
parents:
diff changeset
  3447
	// We always step from the current PC.
hgs
parents:
diff changeset
  3448
	err = ReadKernelRegisterValue(thread, PC_REGISTER, startAddress);
hgs
parents:
diff changeset
  3449
	if(err != KErrNone)
hgs
parents:
diff changeset
  3450
		{
hgs
parents:
diff changeset
  3451
		LOG_MSG2("DRM_DebugChannel::Step - Could not read the PC: %d", err);
hgs
parents:
diff changeset
  3452
hgs
parents:
diff changeset
  3453
		// Close the handle
hgs
parents:
diff changeset
  3454
		thread->Close(NULL);
hgs
parents:
diff changeset
  3455
hgs
parents:
diff changeset
  3456
		return err;
hgs
parents:
diff changeset
  3457
		}
hgs
parents:
diff changeset
  3458
hgs
parents:
diff changeset
  3459
	err = DoStepRange(thread, startAddress, startAddress, ETrue, EFalse, aNumSteps, ETrue);
hgs
parents:
diff changeset
  3460
hgs
parents:
diff changeset
  3461
	if (err != KErrNone)
hgs
parents:
diff changeset
  3462
		{
hgs
parents:
diff changeset
  3463
		// There was a problem, return straightaway
hgs
parents:
diff changeset
  3464
		LOG_MSG("DRM_DebugChannel::Step - failed to step");
hgs
parents:
diff changeset
  3465
		}
hgs
parents:
diff changeset
  3466
hgs
parents:
diff changeset
  3467
	// Close the handle
hgs
parents:
diff changeset
  3468
	thread->Close(NULL);
hgs
parents:
diff changeset
  3469
hgs
parents:
diff changeset
  3470
	return err;
hgs
parents:
diff changeset
  3471
	}
hgs
parents:
diff changeset
  3472
hgs
parents:
diff changeset
  3473
TInt DRM_DebugChannel::KillProcess(const TUint32 aProcessId, const TInt aReason)
hgs
parents:
diff changeset
  3474
	{
hgs
parents:
diff changeset
  3475
	LOG_MSG3("DRM_DebugChannel::KillProcess(aProcessId = 0x%08x, aReason = 0x%08x)\n",aProcessId,aReason);
hgs
parents:
diff changeset
  3476
hgs
parents:
diff changeset
  3477
	DProcess* process = DebugUtils::OpenProcessHandle(aProcessId);
hgs
parents:
diff changeset
  3478
hgs
parents:
diff changeset
  3479
	if (process == NULL)
hgs
parents:
diff changeset
  3480
		{
hgs
parents:
diff changeset
  3481
		// The process terminated before we could open it to kill it ourselves.
hgs
parents:
diff changeset
  3482
		LOG_MSG2("DRM_DebugChannel::KillProcess - Could not open process %u", aProcessId);
hgs
parents:
diff changeset
  3483
hgs
parents:
diff changeset
  3484
		return KErrArgument;
hgs
parents:
diff changeset
  3485
		}
hgs
parents:
diff changeset
  3486
hgs
parents:
diff changeset
  3487
	TInt err = KErrNone;
hgs
parents:
diff changeset
  3488
hgs
parents:
diff changeset
  3489
	DebugSupport::TerminateProcess(process,aReason);
hgs
parents:
diff changeset
  3490
hgs
parents:
diff changeset
  3491
	// Close the handle
hgs
parents:
diff changeset
  3492
	process->Close(NULL);
hgs
parents:
diff changeset
  3493
hgs
parents:
diff changeset
  3494
	return err;
hgs
parents:
diff changeset
  3495
	}
hgs
parents:
diff changeset
  3496
hgs
parents:
diff changeset
  3497
/* Security critical - this checks whether the specified process is debuggable or not
hgs
parents:
diff changeset
  3498
 *
hgs
parents:
diff changeset
  3499
 * @param aProcessId - The process id of the process to check
hgs
parents:
diff changeset
  3500
 * @return KErrNone if debuggable, KErrPermissionDenied if not debuggable.
hgs
parents:
diff changeset
  3501
 */
hgs
parents:
diff changeset
  3502
TInt DRM_DebugChannel::IsDebuggable(const TUint32 aProcessId)
hgs
parents:
diff changeset
  3503
	{
hgs
parents:
diff changeset
  3504
	/* In order to ensure that only processes which are debuggable
hgs
parents:
diff changeset
  3505
	 * can be debugged, this function enables the security server
hgs
parents:
diff changeset
  3506
	 * to read the DProcess.iDebugAttributes field and ensure
hgs
parents:
diff changeset
  3507
	 * the process was created from a debuggable executable.
hgs
parents:
diff changeset
  3508
	 */
hgs
parents:
diff changeset
  3509
	LOG_MSG2("DRM_DebugChannel::IsDebuggable(aProcessId 0x%08x)\n",aProcessId);
hgs
parents:
diff changeset
  3510
hgs
parents:
diff changeset
  3511
	TInt err = KErrPermissionDenied;
hgs
parents:
diff changeset
  3512
hgs
parents:
diff changeset
  3513
	DProcess* process = DebugUtils::OpenProcessHandle(aProcessId);
hgs
parents:
diff changeset
  3514
	if (process)
hgs
parents:
diff changeset
  3515
		{
hgs
parents:
diff changeset
  3516
		if (process->iDebugAttributes & TProcessCreateInfo::EDebugAllowed)
hgs
parents:
diff changeset
  3517
			{
hgs
parents:
diff changeset
  3518
			// Yes this process exists and is debuggable
hgs
parents:
diff changeset
  3519
			err = KErrNone;
hgs
parents:
diff changeset
  3520
			}
hgs
parents:
diff changeset
  3521
		process->Close(NULL);
hgs
parents:
diff changeset
  3522
		}
hgs
parents:
diff changeset
  3523
hgs
parents:
diff changeset
  3524
	if (err == KErrNone)
hgs
parents:
diff changeset
  3525
		{
hgs
parents:
diff changeset
  3526
		LOG_MSG2("DRM_DebugChannel::IsDebuggable(aProcessId 0x%08x) - Yes it is debuggable\n",aProcessId);
hgs
parents:
diff changeset
  3527
		}
hgs
parents:
diff changeset
  3528
hgs
parents:
diff changeset
  3529
	return err;
hgs
parents:
diff changeset
  3530
	}