os/kernelhwsrv/kerneltest/e32test/dll/d_ldrtst.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// f32test\loader\d_ldrtst.cpp
sl@0
    15
// LDD for testing loader
sl@0
    16
// 
sl@0
    17
//
sl@0
    18
sl@0
    19
#include <kernel/kern_priv.h>
sl@0
    20
#include "d_ldrtst.h"
sl@0
    21
sl@0
    22
const TInt KMajorVersionNumber=0;
sl@0
    23
const TInt KMinorVersionNumber=1;
sl@0
    24
const TInt KBuildVersionNumber=1;
sl@0
    25
sl@0
    26
class DLdrTest;
sl@0
    27
class DLdrTestFactory : public DLogicalDevice
sl@0
    28
//
sl@0
    29
// Test LDD factory
sl@0
    30
//
sl@0
    31
	{
sl@0
    32
public:
sl@0
    33
	DLdrTestFactory();
sl@0
    34
	virtual TInt Install();
sl@0
    35
	virtual void GetCaps(TDes8& aDes) const;
sl@0
    36
	virtual TInt Create(DLogicalChannelBase*& aChannel);
sl@0
    37
	};
sl@0
    38
sl@0
    39
class DLdrTest : public DLogicalChannelBase
sl@0
    40
//
sl@0
    41
// Test logical channel
sl@0
    42
//
sl@0
    43
	{
sl@0
    44
public:
sl@0
    45
	virtual ~DLdrTest();
sl@0
    46
protected:
sl@0
    47
	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
sl@0
    48
	virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2);
sl@0
    49
public:
sl@0
    50
	TInt GetCodeSegInfo(TAny* aHandle, TAny* aDest);
sl@0
    51
	TAny* ModuleCodeSeg(TModuleHandle aModuleHandle);
sl@0
    52
	TAny* ProcessCodeSeg(TInt aProcessHandle);
sl@0
    53
	TAny* LibraryCodeSeg(TInt aLibraryHandle);
sl@0
    54
	TInt GetCodeSegList(RLdrTest::SEntry* aList, TInt aMax);
sl@0
    55
	TAny* CodeSegFromAddr(TLinAddr aAddr);
sl@0
    56
	TModuleHandle ModuleHandleFromAddr(TLinAddr aAddr);
sl@0
    57
	TInt ProcessSMPUnsafeCount(TInt aProcessHandle);
sl@0
    58
private:
sl@0
    59
	SDblQueLink* FindCodeSegQueueAnchor();
sl@0
    60
	};
sl@0
    61
sl@0
    62
DECLARE_STANDARD_LDD()
sl@0
    63
	{
sl@0
    64
	return new DLdrTestFactory;
sl@0
    65
	}
sl@0
    66
sl@0
    67
DLdrTestFactory::DLdrTestFactory()
sl@0
    68
//
sl@0
    69
// Constructor
sl@0
    70
//
sl@0
    71
	{
sl@0
    72
	iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
sl@0
    73
	}
sl@0
    74
sl@0
    75
TInt DLdrTestFactory::Create(DLogicalChannelBase*& aChannel)
sl@0
    76
//
sl@0
    77
// Create a new DLdrTest on this logical device
sl@0
    78
//
sl@0
    79
	{
sl@0
    80
	aChannel=new DLdrTest;
sl@0
    81
	return aChannel?KErrNone:KErrNoMemory;
sl@0
    82
	}
sl@0
    83
sl@0
    84
TInt DLdrTestFactory::Install()
sl@0
    85
//
sl@0
    86
// Install the LDD - overriding pure virtual
sl@0
    87
//
sl@0
    88
	{
sl@0
    89
	return SetName(&KLdrTestLddName);
sl@0
    90
	}
sl@0
    91
sl@0
    92
void DLdrTestFactory::GetCaps(TDes8& aDes) const
sl@0
    93
//
sl@0
    94
// Get capabilities - overriding pure virtual
sl@0
    95
//
sl@0
    96
	{
sl@0
    97
	TCapsTestV01 b;
sl@0
    98
	b.iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
sl@0
    99
    Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b));
sl@0
   100
	}
sl@0
   101
sl@0
   102
TInt DLdrTest::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
sl@0
   103
//
sl@0
   104
// Create channel
sl@0
   105
//
sl@0
   106
	{
sl@0
   107
sl@0
   108
	if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer))
sl@0
   109
		return KErrNotSupported;
sl@0
   110
	return KErrNone;
sl@0
   111
	}
sl@0
   112
sl@0
   113
DLdrTest::~DLdrTest()
sl@0
   114
//
sl@0
   115
// Destructor
sl@0
   116
//
sl@0
   117
	{
sl@0
   118
	}
sl@0
   119
sl@0
   120
TInt DLdrTest::GetCodeSegInfo(TAny* aHandle, TAny* aDest)
sl@0
   121
	{
sl@0
   122
	TCodeSegCreateInfo info;
sl@0
   123
	DCodeSeg* pS=DCodeSeg::VerifyHandle(aHandle);
sl@0
   124
	if (pS)
sl@0
   125
		{
sl@0
   126
		Kern::AccessCode();
sl@0
   127
		pS->Info(info);
sl@0
   128
		Kern::EndAccessCode();
sl@0
   129
		kumemput32(aDest, &info, sizeof(info));
sl@0
   130
		return KErrNone;
sl@0
   131
		}
sl@0
   132
	return KErrArgument;
sl@0
   133
	}
sl@0
   134
sl@0
   135
TAny* DLdrTest::ModuleCodeSeg(TModuleHandle aModuleHandle)
sl@0
   136
	{
sl@0
   137
	DCodeSeg* pS=DCodeSeg::VerifyHandle(aModuleHandle);
sl@0
   138
	if(!pS)
sl@0
   139
		{
sl@0
   140
		Kern::AccessCode();
sl@0
   141
		DCodeSeg::CodeSegFromEntryPoint((TLinAddr)aModuleHandle);  // ignore returned DCodeSeg*
sl@0
   142
		Kern::EndAccessCode();
sl@0
   143
		}
sl@0
   144
	return pS;
sl@0
   145
	}
sl@0
   146
sl@0
   147
TAny* DLdrTest::CodeSegFromAddr(TLinAddr aAddr)
sl@0
   148
	{
sl@0
   149
	Kern::AccessCode();
sl@0
   150
	DCodeSeg* s = Kern::CodeSegFromAddress(aAddr, Kern::CurrentThread().iOwningProcess);
sl@0
   151
	Kern::EndAccessCode();
sl@0
   152
	return s;
sl@0
   153
	}
sl@0
   154
sl@0
   155
TModuleHandle DLdrTest::ModuleHandleFromAddr(TLinAddr aAddr)
sl@0
   156
	{
sl@0
   157
	TModuleHandle h = (TModuleHandle)CodeSegFromAddr(aAddr);
sl@0
   158
	if(!h)
sl@0
   159
		h = (TModuleHandle)aAddr;
sl@0
   160
	return h;
sl@0
   161
	}
sl@0
   162
sl@0
   163
TAny* DLdrTest::ProcessCodeSeg(TInt aProcessHandle)
sl@0
   164
	{
sl@0
   165
	DCodeSeg* pS=NULL;
sl@0
   166
	DThread& t=Kern::CurrentThread();
sl@0
   167
	NKern::LockSystem();
sl@0
   168
	DProcess* pP=(DProcess*)t.ObjectFromHandle(aProcessHandle, EProcess);
sl@0
   169
	if (pP)
sl@0
   170
		{
sl@0
   171
		pS=pP->iCodeSeg;
sl@0
   172
		if (!pS)
sl@0
   173
			pS=pP->iTempCodeSeg;
sl@0
   174
		}
sl@0
   175
	NKern::UnlockSystem();
sl@0
   176
	return pS;
sl@0
   177
	}
sl@0
   178
sl@0
   179
TAny* DLdrTest::LibraryCodeSeg(TInt aLibraryHandle)
sl@0
   180
	{
sl@0
   181
	DCodeSeg* pS=NULL;
sl@0
   182
	DThread& t=Kern::CurrentThread();
sl@0
   183
	NKern::LockSystem();
sl@0
   184
	DLibrary* pL=(DLibrary*)t.ObjectFromHandle(aLibraryHandle, ELibrary);
sl@0
   185
	if (pL)
sl@0
   186
		pS=pL->iCodeSeg;
sl@0
   187
	NKern::UnlockSystem();
sl@0
   188
	return pS;
sl@0
   189
	}
sl@0
   190
sl@0
   191
SDblQueLink* DLdrTest::FindCodeSegQueueAnchor()
sl@0
   192
	{
sl@0
   193
	SDblQueLink* p=&iDevice->iCodeSeg->iLink;	// this device driver's code segment
sl@0
   194
	for (;;)
sl@0
   195
		{
sl@0
   196
		p=p->iPrev;
sl@0
   197
		DCodeSeg* s=_LOFF(p, DCodeSeg, iLink);
sl@0
   198
		if (s->iExeCodeSeg==s && (s->iAttr & ECodeSegAttKernel))
sl@0
   199
			{
sl@0
   200
			// s is the kernel's code segment, which is the first one to be created
sl@0
   201
			return s->iLink.iPrev;
sl@0
   202
			}
sl@0
   203
		}
sl@0
   204
	}
sl@0
   205
sl@0
   206
TInt DLdrTest::GetCodeSegList(RLdrTest::SEntry* aList, TInt aMax)
sl@0
   207
	{
sl@0
   208
	if (aMax<=0)
sl@0
   209
		return KErrArgument;
sl@0
   210
	RLdrTest::SEntry list[128];
sl@0
   211
	Kern::AccessCode();
sl@0
   212
	SDblQueLink* anchor=FindCodeSegQueueAnchor();
sl@0
   213
	SDblQueLink* p=anchor->iNext;
sl@0
   214
	if (aMax>128)
sl@0
   215
		aMax=128;
sl@0
   216
	TInt n=0;
sl@0
   217
	for(; p!=anchor && n<aMax; p=p->iNext, ++n)
sl@0
   218
		{
sl@0
   219
		DCodeSeg* s=_LOFF(p, DCodeSeg, iLink);
sl@0
   220
		list[n].iHandle=s;
sl@0
   221
		list[n].iUid3=(TUint32)s->iUids.iUid[2].iUid;
sl@0
   222
		}
sl@0
   223
	Kern::EndAccessCode();
sl@0
   224
	if (n>0)
sl@0
   225
		kumemput32(aList, list, n*sizeof(RLdrTest::SEntry));
sl@0
   226
	return n;
sl@0
   227
	}
sl@0
   228
sl@0
   229
TInt DLdrTest::ProcessSMPUnsafeCount(TInt aProcessHandle)
sl@0
   230
	{
sl@0
   231
	TInt count=KErrNotFound;
sl@0
   232
	DThread& t=Kern::CurrentThread();
sl@0
   233
	NKern::LockSystem();
sl@0
   234
	DProcess* pP=(DProcess*)t.ObjectFromHandle(aProcessHandle, EProcess);
sl@0
   235
	if (pP)
sl@0
   236
		count=pP->iSMPUnsafeCount;
sl@0
   237
	NKern::UnlockSystem();
sl@0
   238
	return count;
sl@0
   239
	}
sl@0
   240
sl@0
   241
TInt DLdrTest::Request(TInt aFunction, TAny* a1, TAny* a2)
sl@0
   242
	{
sl@0
   243
	TInt r=KErrNone;
sl@0
   244
	switch (aFunction)
sl@0
   245
		{
sl@0
   246
		case RLdrTest::EControlGetCodeSegInfo:
sl@0
   247
			r=GetCodeSegInfo(a1,a2);
sl@0
   248
 			break;
sl@0
   249
		case RLdrTest::EControlProcessCodeSeg:
sl@0
   250
			r=(TInt)ProcessCodeSeg((TInt)a1);
sl@0
   251
 			break;
sl@0
   252
		case RLdrTest::EControlLibraryCodeSeg:
sl@0
   253
			r=(TInt)LibraryCodeSeg((TInt)a1);
sl@0
   254
 			break;
sl@0
   255
		case RLdrTest::EControlModuleCodeSeg:
sl@0
   256
			r=(TInt)ModuleCodeSeg((TModuleHandle)a1);
sl@0
   257
 			break;
sl@0
   258
		case RLdrTest::EControlGetCodeSegList:
sl@0
   259
			r=GetCodeSegList( (RLdrTest::SEntry*)a1, (TInt)a2 );
sl@0
   260
			break;
sl@0
   261
		case RLdrTest::EControlCodeSegFromAddr:
sl@0
   262
			r=(TInt)CodeSegFromAddr((TLinAddr)a1);
sl@0
   263
 			break;
sl@0
   264
		case RLdrTest::EControlModuleHandleFromAddr:
sl@0
   265
			r=(TInt)ModuleHandleFromAddr((TLinAddr)a1);
sl@0
   266
 			break;
sl@0
   267
		case RLdrTest::EControlProcessSMPUnsafeCount:
sl@0
   268
			r=ProcessSMPUnsafeCount((TInt)a1);
sl@0
   269
			break;
sl@0
   270
		default:
sl@0
   271
			r=KErrNotSupported;
sl@0
   272
			break;
sl@0
   273
		}
sl@0
   274
	return r;
sl@0
   275
	}
sl@0
   276