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