diff -r 000000000000 -r a41df078684a kernel/eka/memmodel/epoc/pcodeseg.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel/eka/memmodel/epoc/pcodeseg.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,387 @@ +// Copyright (c) 1995-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: +// e32\memmodel\epoc\pcodeseg.cpp +// +// + +#include "plat_priv.h" +#include + +TLinAddr DCodeSeg::ExceptionDescriptor() + { + DEpocCodeSeg* s = (DEpocCodeSeg*)this; + if (s->iXIP) + return s->RomInfo().iExceptionDescriptor; + return s->RamInfo().iExceptionDescriptor; + } + +DEpocCodeSeg::~DEpocCodeSeg() + { + if (!iXIP && iMemory) + { + iMemory->iCodeSeg = 0; + iMemory->Close(); + iMemory = NULL; + } + } + +void DEpocCodeSeg::Destruct() + { + DCodeSeg::Wait(); + + if (iLoaderCookie!=NULL) + { + if ((TInt) iLoaderCookie&1) // Not set fully loaded + { + iLoaderCookie = (TCodeSegLoaderCookieList*) ( ((TInt) iLoaderCookie) & ~1); + delete iLoaderCookie; + iLoaderCookie=NULL; + } + else + { + // Notify reaper of destruction + NKern::LockSystem(); + if (DestructNotifyRequest->IsReady()) + { + DThread* t = DestructNotifyThread; + DestructNotifyThread = NULL; + Kern::QueueRequestComplete(t, DestructNotifyRequest,KErrNone); + } + NKern::UnlockSystem(); + + iLoaderCookie->iNext=DestructNotifyList; + DestructNotifyList=iLoaderCookie; + iLoaderCookie=NULL; + } + } + + DCodeSeg::Signal(); + DCodeSeg::Destruct(); + } + +void DEpocCodeSeg::Info(TCodeSegCreateInfo& aInfo) + { + CHECK_PAGING_SAFE; + if (iXIP) + { + const TRomImageHeader& rih=RomInfo(); + aInfo.iCodeSize=rih.iCodeSize; + aInfo.iTextSize=rih.iTextSize; + aInfo.iDataSize=rih.iDataSize; + aInfo.iBssSize=rih.iBssSize; + aInfo.iTotalDataSize=rih.iTotalDataSize; + aInfo.iExportDir=rih.iExportDir; + aInfo.iExportDirCount=rih.iExportDirCount; + aInfo.iCodeLoadAddress=rih.iCodeAddress; + aInfo.iCodeRunAddress=rih.iCodeAddress; + aInfo.iDataLoadAddress=rih.iDataAddress; + aInfo.iDataRunAddress=rih.iDataBssLinearBase; + aInfo.iExceptionDescriptor = rih.iExceptionDescriptor; + } + else + { + const SRamCodeInfo& ri=RamInfo(); + aInfo.iCodeSize=ri.iCodeSize; + aInfo.iTextSize=ri.iTextSize; + aInfo.iDataSize=ri.iDataSize; + aInfo.iBssSize=ri.iBssSize; + aInfo.iTotalDataSize=ri.iDataSize+ri.iBssSize; + aInfo.iExportDir=ri.iExportDir; + aInfo.iExportDirCount=ri.iExportDirCount; + aInfo.iCodeLoadAddress=ri.iCodeLoadAddr; + aInfo.iCodeRunAddress=ri.iCodeRunAddr; + aInfo.iDataLoadAddress=ri.iDataLoadAddr; + aInfo.iDataRunAddress=ri.iDataRunAddr; + aInfo.iExceptionDescriptor = ri.iExceptionDescriptor; + } + DCodeSeg::Info(aInfo); + } + +void DEpocCodeSeg::GetDataSizeAndBase(TInt& aTotalDataSizeOut, TLinAddr& aDataBaseOut) + { + if (iXIP) + { + aTotalDataSizeOut=RomInfo().iTotalDataSize; + aDataBaseOut=RomInfo().iDataBssLinearBase; + } + else + { + aTotalDataSizeOut=RamInfo().iDataSize+RamInfo().iBssSize; + aDataBaseOut=RamInfo().iDataRunAddr; + } + } + +TLibraryFunction DEpocCodeSeg::Lookup(TInt aOrdinal) + { + CHECK_PAGING_SAFE; + // return NULL for -ve ordinal or 0th ordinal when not stddll/stdexe + if (aOrdinal<0 || (aOrdinal==0 && !(iAttr&ECodeSegAttNmdExpData))) + return NULL; + TInt xdc; + TLinAddr* xd; // points to the 0th ordinal of export table + if (iXIP) + { + const TRomImageHeader& rih=RomInfo(); + xdc=rih.iExportDirCount; + xd=(TLinAddr*)rih.iExportDir - 1; + } + else + { + SRamCodeInfo& ri=RamInfo(); + xdc=ri.iExportDirCount; + xd=(TLinAddr*)ri.iExportDir - 1; + } + if (aOrdinal <= xdc) + { + UNLOCK_USER_MEMORY(); + TLibraryFunction f=(TLibraryFunction)xd[aOrdinal]; + LOCK_USER_MEMORY(); + if ((TLinAddr)f == iFileEntryPoint) + f = NULL; + __KTRACE_OPT(KDLL,Kern::Printf("Lookup(%d)->%08x",aOrdinal,f)); + return f; + } + __KTRACE_OPT(KDLL,Kern::Printf("Lookup(%d)->NULL",aOrdinal)); + return NULL; + } + +TInt DEpocCodeSeg::GetMemoryInfo(TModuleMemoryInfo& aInfo, DProcess*) + { + CHECK_PAGING_SAFE; + if (iXIP) + { + const TRomImageHeader& rih = RomInfo(); + aInfo.iCodeBase = rih.iCodeAddress; + aInfo.iCodeSize = rih.iTextSize; + aInfo.iConstDataSize = rih.iCodeSize - aInfo.iCodeSize; + aInfo.iConstDataBase = (aInfo.iConstDataSize > 0) ? (aInfo.iCodeBase + aInfo.iCodeSize) : 0; + aInfo.iInitialisedDataBase = rih.iDataBssLinearBase; + aInfo.iInitialisedDataSize = rih.iDataSize; + aInfo.iUninitialisedDataSize = rih.iBssSize; + aInfo.iUninitialisedDataBase = aInfo.iInitialisedDataBase+aInfo.iInitialisedDataSize; + } + else + { + const SRamCodeInfo& ri = RamInfo(); + aInfo.iCodeBase = ri.iCodeRunAddr; + aInfo.iCodeSize = ri.iTextSize; + aInfo.iConstDataSize = ri.iCodeSize - aInfo.iCodeSize; + aInfo.iConstDataBase = (aInfo.iConstDataSize > 0) ? (aInfo.iCodeBase + aInfo.iCodeSize) : 0; + aInfo.iInitialisedDataBase = ri.iDataRunAddr; + aInfo.iInitialisedDataSize = ri.iDataSize; + aInfo.iUninitialisedDataSize = ri.iBssSize; + aInfo.iUninitialisedDataBase = aInfo.iInitialisedDataBase + aInfo.iInitialisedDataSize; + } + return KErrNone; + } + +//const TUint32 KRomImageFlagsAlwaysLoaded=KRomImageFlagPrimary|KRomImageFlagVariant|KRomImageFlagExtension; +const TUint32 KRomImageDataFlags=(KRomImageFlagData|KRomImageFlagDataInit|KRomImageFlagDataPresent); +TInt DEpocCodeSeg::DoCreate(TCodeSegCreateInfo& aInfo, DProcess* aProcess) + { + __KTRACE_OPT(KDLL,Kern::Printf(">DEpocCodeSeg::DoCreate code_addr=%08x",aInfo.iCodeLoadAddress)); + CHECK_PAGING_SAFE; + TInt r=KErrNone; + TBool exeSeg=(iExeCodeSeg==this); + TBool kp=exeSeg && (aProcess->iAttributes&DProcess::ESupervisor); + TBool user_proc=exeSeg && !kp; + if (aInfo.iCodeLoadAddress) + { + iXIP=ETrue; + iInfo=(const TAny*)aInfo.iCodeLoadAddress; + } + if (user_proc) + { + r=aProcess->CreateDataBssStackArea((TProcessCreateInfo&)aInfo); + if (r!=KErrNone) + return r; + } + if (iXIP) + { + const TRomImageHeader& rih=RomInfo(); + iXIP=ETrue; + if ( (rih.iFlags & (KRomImageFlagExeInTree|KRomImageFlagDll)) == (KRomImageFlagExeInTree|KRomImageFlagDll)) + { + const TRomImageHeader* exeRIH=rih.iDllRefTable->iEntry[0]; // EXE is always first entry + if (aProcess) + { + DEpocCodeSeg* pS=(DEpocCodeSeg*)aProcess->CodeSeg(); + if (!pS->iXIP || &pS->RomInfo()!=exeRIH) + return KErrNotSupported; + iExeCodeSeg=pS; + } + } + + iMark |= (rih.iFlags & KRomImageDataFlags); + iMark |= EMarkRecursiveFlagsValid; + __KTRACE_OPT(KDLL,Kern::Printf("ROM Code Seg: mark %08x attr=%02x",iMark,iAttr)); + aInfo.iFileEntryPoint=rih.iEntryPoint; + aInfo.iExportDir=rih.iExportDir; + aInfo.iCodeLoadAddress=rih.iCodeAddress; + aInfo.iCodeRunAddress=rih.iCodeAddress; + iRunAddress = rih.iCodeAddress; + iSize = rih.iCodeSize; + aInfo.iDataLoadAddress=rih.iDataAddress; + if (aInfo.iTotalDataSize && user_proc && aProcess->iDataBssRunAddress!=rih.iDataBssLinearBase) + K::Fault(K::EProcessDataAddressInvalid); + aInfo.iDataRunAddress=rih.iDataBssLinearBase; + aInfo.iExceptionDescriptor = rih.iExceptionDescriptor; + r=DoCreateXIP(aProcess); + return r; + } + iMemory = DEpocCodeSegMemory::New(this); + if (!iMemory) + return KErrNoMemory; + iInfo = &iMemory->iRamInfo; + + if (aInfo.iUseCodePaging) + { + if ((aInfo.iCodeBlockMapEntries==NULL) || (aInfo.iCodeBlockMapCommon.iLocalDriveNumber<0) || + (((TInt64) (aInfo.iFileClamp.iCookie[0] | aInfo.iFileClamp.iCookie[1]))==0)) + return KErrArgument; + + iLoaderCookie = new TCodeSegLoaderCookieList(); + if (!iLoaderCookie) + return KErrNoMemory; + + SBlockMapInfoBase* cbm = &aInfo.iCodeBlockMapCommon; + + TUint startBlock; + kumemget32(&startBlock, &aInfo.iCodeBlockMapEntries->iStartBlock, sizeof(TUint)); + + iLoaderCookie->iCookie.iDriveNumber = cbm->iLocalDriveNumber; + iLoaderCookie->iCookie.iStartAddress = cbm->iStartBlockAddress + + startBlock * + cbm->iBlockGranularity + + cbm->iBlockStartOffset; + iLoaderCookie->iCookie.iFileClamp = aInfo.iFileClamp; + // Mark cookie not to be closed yet + iLoaderCookie = (TCodeSegLoaderCookieList*) ( ((TInt) iLoaderCookie) | 1); + } + + SRamCodeInfo& ri=RamInfo(); + ri.iCodeSize=aInfo.iCodeSize; + ri.iTextSize=aInfo.iTextSize; + ri.iDataSize=aInfo.iDataSize; + ri.iBssSize=aInfo.iBssSize; + TInt total_data_size=ri.iDataSize+ri.iBssSize; + ri.iExportDirCount=aInfo.iExportDirCount; + if (total_data_size!=0) + { + iMark|=(EMarkData|EMarkDataPresent); + if (!exeSeg) + iMark|=EMarkDataInit; + } + // if this DLL/EXE doesn't have data, don't set valid bit since we don't yet know about its dependencies + + if (exeSeg) + ri.iDataRunAddr=aProcess->iDataBssRunAddress; + r=DoCreateRam(aInfo, aProcess); + if (r==KErrNone) + { + aInfo.iFileEntryPoint+=ri.iCodeRunAddr; + aInfo.iExportDir+=ri.iCodeRunAddr; + ri.iExportDir=aInfo.iExportDir; + aInfo.iCodeLoadAddress=ri.iCodeLoadAddr; + aInfo.iCodeRunAddress=ri.iCodeRunAddr; + aInfo.iDataLoadAddress=ri.iDataLoadAddr; + aInfo.iDataRunAddress=ri.iDataRunAddr; + TUint32 xd = aInfo.iExceptionDescriptor; + ri.iExceptionDescriptor = xd ? (xd + ri.iCodeRunAddr) : 0; + aInfo.iExceptionDescriptor = ri.iExceptionDescriptor; + iRunAddress = ri.iCodeRunAddr; + } + __KTRACE_OPT(KDLL,Kern::Printf("RAM Code Seg: mark %08x attr=%02x xd=%08x",iMark,iAttr,ri.iExceptionDescriptor)); + __KTRACE_OPT(KDLL,Kern::Printf("