os/kernelhwsrv/kernel/eka/drivers/debug/smdebug/d_sm_codeseg.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // Stop-mode debug interface implementation as defined in sm_debug_api.h
    15 //
    16 
    17 /**
    18  * @file
    19  * @internalComponent
    20  * @prototype
    21 */
    22 
    23 #ifdef __LAUNCH_AS_EXTENSION__
    24 
    25 #include <rm_debug_api.h>
    26 #include <sm_debug_api.h>
    27 #include "d_rmd_breakpoints.h"
    28 
    29 using namespace Debug;
    30 
    31 /**
    32  * Stop Mode routine to retrieve the code seg list and place it in the response buffer
    33  * @param aItem List item describing the list
    34  * @return One of the system wide error codes
    35  */
    36 TInt StopModeDebug::GetCodeSegList(const TListItem* aItem, bool aCheckConsistent)
    37 	{
    38 	if(aCheckConsistent)
    39 		{
    40 		DMutex* codeMutex = Kern::CodeSegLock();
    41 		if(!codeMutex || codeMutex->iHoldCount)
    42 			{
    43 			return ExitPoint(KErrNotReady);
    44 			}
    45 		}
    46 
    47 	TUint8* bufferInitial = (TUint8*)aItem->iBufferAddress;
    48 	TUint8* buffer = (TUint8*)aItem->iBufferAddress + 12;
    49 	TUint32 bufferSize = aItem->iBufferSize;
    50 
    51 	TUint32* buffer32 = (TUint32*)aItem->iBufferAddress;
    52 	*buffer32 = (TUint32)aItem;
    53 	TUint32* size = buffer32+1;
    54 	*size = 12;
    55 	TUint32* nextElementSize = buffer32+2;
    56 	*nextElementSize = 0;
    57 	TUint32 start = aItem->iStartElement;
    58 
    59 	while(1)
    60 		{
    61 		DEpocCodeSeg* codeSeg = GetNextCodeSeg(start, aItem->iListScope, aItem->iScopeData);
    62 		if(!codeSeg)
    63 			{
    64 			*size = buffer-bufferInitial;
    65 			return KErrNone; // we're done
    66 			}
    67 		start = (TUint32)codeSeg + 1;
    68 
    69 		TInt ret = ProcessCodeSeg(buffer, bufferSize, codeSeg);
    70 		if(KErrNone != ret)
    71 			{
    72 			if(ret > 0)
    73 				{
    74 				Kern::Printf("Next element is %d bytes big\n", ret);
    75 				*nextElementSize = ret;
    76 				ret = KErrTooBig;
    77 				}
    78 			*size = buffer-bufferInitial;
    79 			return ret;
    80 			}
    81 		}
    82 	}
    83 
    84 DEpocCodeSeg* StopModeDebug::GetNextCodeSeg(const TUint32 aStart, const TListScope aListScope, const TUint64 aScopeData)
    85 	{
    86 	switch(aListScope)
    87 		{
    88 		case EScopeGlobal:
    89 			return GetNextGlobalCodeSeg(aStart);
    90 		case EScopeThreadSpecific:
    91 			return GetNextThreadSpecificCodeSeg(aStart, aScopeData);
    92 		default:
    93 			return NULL;
    94 		}
    95 	}
    96 
    97 DEpocCodeSeg* StopModeDebug::GetNextThreadSpecificCodeSeg(const TUint32 aStart, const TUint64 aThreadId)
    98 	{
    99 	return NULL;
   100 	}
   101 
   102 DEpocCodeSeg* StopModeDebug::GetNextGlobalCodeSeg(const TUint32 aStart)
   103 	{
   104 	//get global code seg list
   105 	SDblQue* codeSegList = Kern::CodeSegList();
   106 
   107 	DEpocCodeSeg* codeSeg = NULL;
   108 	for (SDblQueLink* codeSegPtr= codeSegList->First(); codeSegPtr!=(SDblQueLink*) (codeSegList); codeSegPtr=codeSegPtr->iNext)
   109 		{
   110 		DEpocCodeSeg* tempCodeSeg = (DEpocCodeSeg*)_LOFF(codeSegPtr,DCodeSeg, iLink);
   111 		if((TUint32)tempCodeSeg >= aStart)
   112 			{
   113 			if(!codeSeg || tempCodeSeg < codeSeg)
   114 				{
   115 				codeSeg = tempCodeSeg;
   116 				}
   117 			}
   118 		}
   119 	return codeSeg;
   120 	}
   121 
   122 TInt StopModeDebug::ProcessCodeSeg(TUint8*& aBuffer, TUint32& aBufferSize, DEpocCodeSeg* aCodeSeg)
   123 	{
   124 	//create a memory info object for use in the loop
   125 	TModuleMemoryInfo memoryInfo;
   126 
   127 	//get the memory info
   128 	TInt err = aCodeSeg->GetMemoryInfo(memoryInfo, NULL);
   129 	if(err != KErrNone)
   130 		{
   131 		//there's been an error so return it
   132 		return err;
   133 		}
   134 	//calculate data values
   135 	TFileName fileName(aCodeSeg->iFileName->Ptr());
   136 	TBool isXip = (aCodeSeg->iXIP) ? ETrue : EFalse;
   137 
   138 	//get the code seg type
   139 	TCodeSegType type =
   140 		aCodeSeg->IsExe() ? EExeCodeSegType :
   141 		aCodeSeg->IsDll() ? EDllCodeSegType :
   142 		EUnknownCodeSegType;
   143 
   144 	//append data to buffer
   145 	return AppendCodeSegData(aBuffer, aBufferSize, memoryInfo, isXip, type, fileName, aCodeSeg);
   146 	}
   147 
   148 TInt StopModeDebug::AppendCodeSegData(TUint8*& aBuffer, TUint32& aBufferSize, const TModuleMemoryInfo& aMemoryInfo, const TBool aIsXip, const TCodeSegType aCodeSegType, const TDesC8& aFileName, DEpocCodeSeg* aCodeSeg)
   149 	{
   150 	//get some data elements to put in buffer
   151 	TUint16 fileNameLength = aFileName.Length();
   152 
   153 	//calculate the resultant size
   154 	TUint dataSize = Align4(sizeof(TCodeSegListEntry) + (2*fileNameLength) - sizeof(TUint16));
   155 	if(dataSize > aBufferSize)
   156 		{
   157 		// data won't fit in the buffer so quit
   158 		return dataSize;
   159 		}
   160 	//Create a TCodeSegListEntry which references the buffer.
   161 	TCodeSegListEntry& entry = *(TCodeSegListEntry*)aBuffer;
   162 	entry.iCodeBase = aMemoryInfo.iCodeBase;
   163 	entry.iCodeSize = aMemoryInfo.iCodeSize;
   164 	entry.iConstDataSize = aMemoryInfo.iConstDataSize;
   165 	entry.iInitialisedDataBase = aMemoryInfo.iInitialisedDataBase;
   166 	entry.iInitialisedDataSize = aMemoryInfo.iInitialisedDataSize;
   167 	entry.iUninitialisedDataSize = aMemoryInfo.iUninitialisedDataSize;
   168 	entry.iIsXip = aIsXip;
   169 	entry.iCodeSegType = aCodeSegType;
   170 	entry.iNameLength = fileNameLength;
   171 	//entry.iSpare1 = (TUint32)aCodeSeg;
   172 
   173 	//have to convert the stored name to 16 bit Unicode
   174 	TPtr name = TPtr((TUint8*)&(entry.iName[0]), fileNameLength*2, fileNameLength*2);
   175 	TInt err = CopyAndExpandDes(aFileName, name);
   176 	if(err != KErrNone)
   177 		{
   178 		return KErrGeneral;
   179 		}
   180 
   181 	//increase length         
   182 	aBufferSize-=dataSize;
   183 	aBuffer+=dataSize;
   184 	return KErrNone;
   185 	}
   186 
   187 #endif
   188