diff -r 000000000000 -r a41df078684a kerneltest/e32test/dll/d_ldrtst.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/dll/d_ldrtst.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,276 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// f32test\loader\d_ldrtst.cpp +// LDD for testing loader +// +// + +#include +#include "d_ldrtst.h" + +const TInt KMajorVersionNumber=0; +const TInt KMinorVersionNumber=1; +const TInt KBuildVersionNumber=1; + +class DLdrTest; +class DLdrTestFactory : public DLogicalDevice +// +// Test LDD factory +// + { +public: + DLdrTestFactory(); + virtual TInt Install(); + virtual void GetCaps(TDes8& aDes) const; + virtual TInt Create(DLogicalChannelBase*& aChannel); + }; + +class DLdrTest : public DLogicalChannelBase +// +// Test logical channel +// + { +public: + virtual ~DLdrTest(); +protected: + virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); + virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2); +public: + TInt GetCodeSegInfo(TAny* aHandle, TAny* aDest); + TAny* ModuleCodeSeg(TModuleHandle aModuleHandle); + TAny* ProcessCodeSeg(TInt aProcessHandle); + TAny* LibraryCodeSeg(TInt aLibraryHandle); + TInt GetCodeSegList(RLdrTest::SEntry* aList, TInt aMax); + TAny* CodeSegFromAddr(TLinAddr aAddr); + TModuleHandle ModuleHandleFromAddr(TLinAddr aAddr); + TInt ProcessSMPUnsafeCount(TInt aProcessHandle); +private: + SDblQueLink* FindCodeSegQueueAnchor(); + }; + +DECLARE_STANDARD_LDD() + { + return new DLdrTestFactory; + } + +DLdrTestFactory::DLdrTestFactory() +// +// Constructor +// + { + iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); + } + +TInt DLdrTestFactory::Create(DLogicalChannelBase*& aChannel) +// +// Create a new DLdrTest on this logical device +// + { + aChannel=new DLdrTest; + return aChannel?KErrNone:KErrNoMemory; + } + +TInt DLdrTestFactory::Install() +// +// Install the LDD - overriding pure virtual +// + { + return SetName(&KLdrTestLddName); + } + +void DLdrTestFactory::GetCaps(TDes8& aDes) const +// +// Get capabilities - overriding pure virtual +// + { + TCapsTestV01 b; + b.iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); + Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b)); + } + +TInt DLdrTest::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer) +// +// Create channel +// + { + + if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer)) + return KErrNotSupported; + return KErrNone; + } + +DLdrTest::~DLdrTest() +// +// Destructor +// + { + } + +TInt DLdrTest::GetCodeSegInfo(TAny* aHandle, TAny* aDest) + { + TCodeSegCreateInfo info; + DCodeSeg* pS=DCodeSeg::VerifyHandle(aHandle); + if (pS) + { + Kern::AccessCode(); + pS->Info(info); + Kern::EndAccessCode(); + kumemput32(aDest, &info, sizeof(info)); + return KErrNone; + } + return KErrArgument; + } + +TAny* DLdrTest::ModuleCodeSeg(TModuleHandle aModuleHandle) + { + DCodeSeg* pS=DCodeSeg::VerifyHandle(aModuleHandle); + if(!pS) + { + Kern::AccessCode(); + DCodeSeg::CodeSegFromEntryPoint((TLinAddr)aModuleHandle); // ignore returned DCodeSeg* + Kern::EndAccessCode(); + } + return pS; + } + +TAny* DLdrTest::CodeSegFromAddr(TLinAddr aAddr) + { + Kern::AccessCode(); + DCodeSeg* s = Kern::CodeSegFromAddress(aAddr, Kern::CurrentThread().iOwningProcess); + Kern::EndAccessCode(); + return s; + } + +TModuleHandle DLdrTest::ModuleHandleFromAddr(TLinAddr aAddr) + { + TModuleHandle h = (TModuleHandle)CodeSegFromAddr(aAddr); + if(!h) + h = (TModuleHandle)aAddr; + return h; + } + +TAny* DLdrTest::ProcessCodeSeg(TInt aProcessHandle) + { + DCodeSeg* pS=NULL; + DThread& t=Kern::CurrentThread(); + NKern::LockSystem(); + DProcess* pP=(DProcess*)t.ObjectFromHandle(aProcessHandle, EProcess); + if (pP) + { + pS=pP->iCodeSeg; + if (!pS) + pS=pP->iTempCodeSeg; + } + NKern::UnlockSystem(); + return pS; + } + +TAny* DLdrTest::LibraryCodeSeg(TInt aLibraryHandle) + { + DCodeSeg* pS=NULL; + DThread& t=Kern::CurrentThread(); + NKern::LockSystem(); + DLibrary* pL=(DLibrary*)t.ObjectFromHandle(aLibraryHandle, ELibrary); + if (pL) + pS=pL->iCodeSeg; + NKern::UnlockSystem(); + return pS; + } + +SDblQueLink* DLdrTest::FindCodeSegQueueAnchor() + { + SDblQueLink* p=&iDevice->iCodeSeg->iLink; // this device driver's code segment + for (;;) + { + p=p->iPrev; + DCodeSeg* s=_LOFF(p, DCodeSeg, iLink); + if (s->iExeCodeSeg==s && (s->iAttr & ECodeSegAttKernel)) + { + // s is the kernel's code segment, which is the first one to be created + return s->iLink.iPrev; + } + } + } + +TInt DLdrTest::GetCodeSegList(RLdrTest::SEntry* aList, TInt aMax) + { + if (aMax<=0) + return KErrArgument; + RLdrTest::SEntry list[128]; + Kern::AccessCode(); + SDblQueLink* anchor=FindCodeSegQueueAnchor(); + SDblQueLink* p=anchor->iNext; + if (aMax>128) + aMax=128; + TInt n=0; + for(; p!=anchor && niNext, ++n) + { + DCodeSeg* s=_LOFF(p, DCodeSeg, iLink); + list[n].iHandle=s; + list[n].iUid3=(TUint32)s->iUids.iUid[2].iUid; + } + Kern::EndAccessCode(); + if (n>0) + kumemput32(aList, list, n*sizeof(RLdrTest::SEntry)); + return n; + } + +TInt DLdrTest::ProcessSMPUnsafeCount(TInt aProcessHandle) + { + TInt count=KErrNotFound; + DThread& t=Kern::CurrentThread(); + NKern::LockSystem(); + DProcess* pP=(DProcess*)t.ObjectFromHandle(aProcessHandle, EProcess); + if (pP) + count=pP->iSMPUnsafeCount; + NKern::UnlockSystem(); + return count; + } + +TInt DLdrTest::Request(TInt aFunction, TAny* a1, TAny* a2) + { + TInt r=KErrNone; + switch (aFunction) + { + case RLdrTest::EControlGetCodeSegInfo: + r=GetCodeSegInfo(a1,a2); + break; + case RLdrTest::EControlProcessCodeSeg: + r=(TInt)ProcessCodeSeg((TInt)a1); + break; + case RLdrTest::EControlLibraryCodeSeg: + r=(TInt)LibraryCodeSeg((TInt)a1); + break; + case RLdrTest::EControlModuleCodeSeg: + r=(TInt)ModuleCodeSeg((TModuleHandle)a1); + break; + case RLdrTest::EControlGetCodeSegList: + r=GetCodeSegList( (RLdrTest::SEntry*)a1, (TInt)a2 ); + break; + case RLdrTest::EControlCodeSegFromAddr: + r=(TInt)CodeSegFromAddr((TLinAddr)a1); + break; + case RLdrTest::EControlModuleHandleFromAddr: + r=(TInt)ModuleHandleFromAddr((TLinAddr)a1); + break; + case RLdrTest::EControlProcessSMPUnsafeCount: + r=ProcessSMPUnsafeCount((TInt)a1); + break; + default: + r=KErrNotSupported; + break; + } + return r; + } +