1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/memmodel/epoc/pcodeseg.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,387 @@
1.4 +// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32\memmodel\epoc\pcodeseg.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#include "plat_priv.h"
1.22 +#include <e32uid.h>
1.23 +
1.24 +TLinAddr DCodeSeg::ExceptionDescriptor()
1.25 + {
1.26 + DEpocCodeSeg* s = (DEpocCodeSeg*)this;
1.27 + if (s->iXIP)
1.28 + return s->RomInfo().iExceptionDescriptor;
1.29 + return s->RamInfo().iExceptionDescriptor;
1.30 + }
1.31 +
1.32 +DEpocCodeSeg::~DEpocCodeSeg()
1.33 + {
1.34 + if (!iXIP && iMemory)
1.35 + {
1.36 + iMemory->iCodeSeg = 0;
1.37 + iMemory->Close();
1.38 + iMemory = NULL;
1.39 + }
1.40 + }
1.41 +
1.42 +void DEpocCodeSeg::Destruct()
1.43 + {
1.44 + DCodeSeg::Wait();
1.45 +
1.46 + if (iLoaderCookie!=NULL)
1.47 + {
1.48 + if ((TInt) iLoaderCookie&1) // Not set fully loaded
1.49 + {
1.50 + iLoaderCookie = (TCodeSegLoaderCookieList*) ( ((TInt) iLoaderCookie) & ~1);
1.51 + delete iLoaderCookie;
1.52 + iLoaderCookie=NULL;
1.53 + }
1.54 + else
1.55 + {
1.56 + // Notify reaper of destruction
1.57 + NKern::LockSystem();
1.58 + if (DestructNotifyRequest->IsReady())
1.59 + {
1.60 + DThread* t = DestructNotifyThread;
1.61 + DestructNotifyThread = NULL;
1.62 + Kern::QueueRequestComplete(t, DestructNotifyRequest,KErrNone);
1.63 + }
1.64 + NKern::UnlockSystem();
1.65 +
1.66 + iLoaderCookie->iNext=DestructNotifyList;
1.67 + DestructNotifyList=iLoaderCookie;
1.68 + iLoaderCookie=NULL;
1.69 + }
1.70 + }
1.71 +
1.72 + DCodeSeg::Signal();
1.73 + DCodeSeg::Destruct();
1.74 + }
1.75 +
1.76 +void DEpocCodeSeg::Info(TCodeSegCreateInfo& aInfo)
1.77 + {
1.78 + CHECK_PAGING_SAFE;
1.79 + if (iXIP)
1.80 + {
1.81 + const TRomImageHeader& rih=RomInfo();
1.82 + aInfo.iCodeSize=rih.iCodeSize;
1.83 + aInfo.iTextSize=rih.iTextSize;
1.84 + aInfo.iDataSize=rih.iDataSize;
1.85 + aInfo.iBssSize=rih.iBssSize;
1.86 + aInfo.iTotalDataSize=rih.iTotalDataSize;
1.87 + aInfo.iExportDir=rih.iExportDir;
1.88 + aInfo.iExportDirCount=rih.iExportDirCount;
1.89 + aInfo.iCodeLoadAddress=rih.iCodeAddress;
1.90 + aInfo.iCodeRunAddress=rih.iCodeAddress;
1.91 + aInfo.iDataLoadAddress=rih.iDataAddress;
1.92 + aInfo.iDataRunAddress=rih.iDataBssLinearBase;
1.93 + aInfo.iExceptionDescriptor = rih.iExceptionDescriptor;
1.94 + }
1.95 + else
1.96 + {
1.97 + const SRamCodeInfo& ri=RamInfo();
1.98 + aInfo.iCodeSize=ri.iCodeSize;
1.99 + aInfo.iTextSize=ri.iTextSize;
1.100 + aInfo.iDataSize=ri.iDataSize;
1.101 + aInfo.iBssSize=ri.iBssSize;
1.102 + aInfo.iTotalDataSize=ri.iDataSize+ri.iBssSize;
1.103 + aInfo.iExportDir=ri.iExportDir;
1.104 + aInfo.iExportDirCount=ri.iExportDirCount;
1.105 + aInfo.iCodeLoadAddress=ri.iCodeLoadAddr;
1.106 + aInfo.iCodeRunAddress=ri.iCodeRunAddr;
1.107 + aInfo.iDataLoadAddress=ri.iDataLoadAddr;
1.108 + aInfo.iDataRunAddress=ri.iDataRunAddr;
1.109 + aInfo.iExceptionDescriptor = ri.iExceptionDescriptor;
1.110 + }
1.111 + DCodeSeg::Info(aInfo);
1.112 + }
1.113 +
1.114 +void DEpocCodeSeg::GetDataSizeAndBase(TInt& aTotalDataSizeOut, TLinAddr& aDataBaseOut)
1.115 + {
1.116 + if (iXIP)
1.117 + {
1.118 + aTotalDataSizeOut=RomInfo().iTotalDataSize;
1.119 + aDataBaseOut=RomInfo().iDataBssLinearBase;
1.120 + }
1.121 + else
1.122 + {
1.123 + aTotalDataSizeOut=RamInfo().iDataSize+RamInfo().iBssSize;
1.124 + aDataBaseOut=RamInfo().iDataRunAddr;
1.125 + }
1.126 + }
1.127 +
1.128 +TLibraryFunction DEpocCodeSeg::Lookup(TInt aOrdinal)
1.129 + {
1.130 + CHECK_PAGING_SAFE;
1.131 + // return NULL for -ve ordinal or 0th ordinal when not stddll/stdexe
1.132 + if (aOrdinal<0 || (aOrdinal==0 && !(iAttr&ECodeSegAttNmdExpData)))
1.133 + return NULL;
1.134 + TInt xdc;
1.135 + TLinAddr* xd; // points to the 0th ordinal of export table
1.136 + if (iXIP)
1.137 + {
1.138 + const TRomImageHeader& rih=RomInfo();
1.139 + xdc=rih.iExportDirCount;
1.140 + xd=(TLinAddr*)rih.iExportDir - 1;
1.141 + }
1.142 + else
1.143 + {
1.144 + SRamCodeInfo& ri=RamInfo();
1.145 + xdc=ri.iExportDirCount;
1.146 + xd=(TLinAddr*)ri.iExportDir - 1;
1.147 + }
1.148 + if (aOrdinal <= xdc)
1.149 + {
1.150 + UNLOCK_USER_MEMORY();
1.151 + TLibraryFunction f=(TLibraryFunction)xd[aOrdinal];
1.152 + LOCK_USER_MEMORY();
1.153 + if ((TLinAddr)f == iFileEntryPoint)
1.154 + f = NULL;
1.155 + __KTRACE_OPT(KDLL,Kern::Printf("Lookup(%d)->%08x",aOrdinal,f));
1.156 + return f;
1.157 + }
1.158 + __KTRACE_OPT(KDLL,Kern::Printf("Lookup(%d)->NULL",aOrdinal));
1.159 + return NULL;
1.160 + }
1.161 +
1.162 +TInt DEpocCodeSeg::GetMemoryInfo(TModuleMemoryInfo& aInfo, DProcess*)
1.163 + {
1.164 + CHECK_PAGING_SAFE;
1.165 + if (iXIP)
1.166 + {
1.167 + const TRomImageHeader& rih = RomInfo();
1.168 + aInfo.iCodeBase = rih.iCodeAddress;
1.169 + aInfo.iCodeSize = rih.iTextSize;
1.170 + aInfo.iConstDataSize = rih.iCodeSize - aInfo.iCodeSize;
1.171 + aInfo.iConstDataBase = (aInfo.iConstDataSize > 0) ? (aInfo.iCodeBase + aInfo.iCodeSize) : 0;
1.172 + aInfo.iInitialisedDataBase = rih.iDataBssLinearBase;
1.173 + aInfo.iInitialisedDataSize = rih.iDataSize;
1.174 + aInfo.iUninitialisedDataSize = rih.iBssSize;
1.175 + aInfo.iUninitialisedDataBase = aInfo.iInitialisedDataBase+aInfo.iInitialisedDataSize;
1.176 + }
1.177 + else
1.178 + {
1.179 + const SRamCodeInfo& ri = RamInfo();
1.180 + aInfo.iCodeBase = ri.iCodeRunAddr;
1.181 + aInfo.iCodeSize = ri.iTextSize;
1.182 + aInfo.iConstDataSize = ri.iCodeSize - aInfo.iCodeSize;
1.183 + aInfo.iConstDataBase = (aInfo.iConstDataSize > 0) ? (aInfo.iCodeBase + aInfo.iCodeSize) : 0;
1.184 + aInfo.iInitialisedDataBase = ri.iDataRunAddr;
1.185 + aInfo.iInitialisedDataSize = ri.iDataSize;
1.186 + aInfo.iUninitialisedDataSize = ri.iBssSize;
1.187 + aInfo.iUninitialisedDataBase = aInfo.iInitialisedDataBase + aInfo.iInitialisedDataSize;
1.188 + }
1.189 + return KErrNone;
1.190 + }
1.191 +
1.192 +//const TUint32 KRomImageFlagsAlwaysLoaded=KRomImageFlagPrimary|KRomImageFlagVariant|KRomImageFlagExtension;
1.193 +const TUint32 KRomImageDataFlags=(KRomImageFlagData|KRomImageFlagDataInit|KRomImageFlagDataPresent);
1.194 +TInt DEpocCodeSeg::DoCreate(TCodeSegCreateInfo& aInfo, DProcess* aProcess)
1.195 + {
1.196 + __KTRACE_OPT(KDLL,Kern::Printf(">DEpocCodeSeg::DoCreate code_addr=%08x",aInfo.iCodeLoadAddress));
1.197 + CHECK_PAGING_SAFE;
1.198 + TInt r=KErrNone;
1.199 + TBool exeSeg=(iExeCodeSeg==this);
1.200 + TBool kp=exeSeg && (aProcess->iAttributes&DProcess::ESupervisor);
1.201 + TBool user_proc=exeSeg && !kp;
1.202 + if (aInfo.iCodeLoadAddress)
1.203 + {
1.204 + iXIP=ETrue;
1.205 + iInfo=(const TAny*)aInfo.iCodeLoadAddress;
1.206 + }
1.207 + if (user_proc)
1.208 + {
1.209 + r=aProcess->CreateDataBssStackArea((TProcessCreateInfo&)aInfo);
1.210 + if (r!=KErrNone)
1.211 + return r;
1.212 + }
1.213 + if (iXIP)
1.214 + {
1.215 + const TRomImageHeader& rih=RomInfo();
1.216 + iXIP=ETrue;
1.217 + if ( (rih.iFlags & (KRomImageFlagExeInTree|KRomImageFlagDll)) == (KRomImageFlagExeInTree|KRomImageFlagDll))
1.218 + {
1.219 + const TRomImageHeader* exeRIH=rih.iDllRefTable->iEntry[0]; // EXE is always first entry
1.220 + if (aProcess)
1.221 + {
1.222 + DEpocCodeSeg* pS=(DEpocCodeSeg*)aProcess->CodeSeg();
1.223 + if (!pS->iXIP || &pS->RomInfo()!=exeRIH)
1.224 + return KErrNotSupported;
1.225 + iExeCodeSeg=pS;
1.226 + }
1.227 + }
1.228 +
1.229 + iMark |= (rih.iFlags & KRomImageDataFlags);
1.230 + iMark |= EMarkRecursiveFlagsValid;
1.231 + __KTRACE_OPT(KDLL,Kern::Printf("ROM Code Seg: mark %08x attr=%02x",iMark,iAttr));
1.232 + aInfo.iFileEntryPoint=rih.iEntryPoint;
1.233 + aInfo.iExportDir=rih.iExportDir;
1.234 + aInfo.iCodeLoadAddress=rih.iCodeAddress;
1.235 + aInfo.iCodeRunAddress=rih.iCodeAddress;
1.236 + iRunAddress = rih.iCodeAddress;
1.237 + iSize = rih.iCodeSize;
1.238 + aInfo.iDataLoadAddress=rih.iDataAddress;
1.239 + if (aInfo.iTotalDataSize && user_proc && aProcess->iDataBssRunAddress!=rih.iDataBssLinearBase)
1.240 + K::Fault(K::EProcessDataAddressInvalid);
1.241 + aInfo.iDataRunAddress=rih.iDataBssLinearBase;
1.242 + aInfo.iExceptionDescriptor = rih.iExceptionDescriptor;
1.243 + r=DoCreateXIP(aProcess);
1.244 + return r;
1.245 + }
1.246 + iMemory = DEpocCodeSegMemory::New(this);
1.247 + if (!iMemory)
1.248 + return KErrNoMemory;
1.249 + iInfo = &iMemory->iRamInfo;
1.250 +
1.251 + if (aInfo.iUseCodePaging)
1.252 + {
1.253 + if ((aInfo.iCodeBlockMapEntries==NULL) || (aInfo.iCodeBlockMapCommon.iLocalDriveNumber<0) ||
1.254 + (((TInt64) (aInfo.iFileClamp.iCookie[0] | aInfo.iFileClamp.iCookie[1]))==0))
1.255 + return KErrArgument;
1.256 +
1.257 + iLoaderCookie = new TCodeSegLoaderCookieList();
1.258 + if (!iLoaderCookie)
1.259 + return KErrNoMemory;
1.260 +
1.261 + SBlockMapInfoBase* cbm = &aInfo.iCodeBlockMapCommon;
1.262 +
1.263 + TUint startBlock;
1.264 + kumemget32(&startBlock, &aInfo.iCodeBlockMapEntries->iStartBlock, sizeof(TUint));
1.265 +
1.266 + iLoaderCookie->iCookie.iDriveNumber = cbm->iLocalDriveNumber;
1.267 + iLoaderCookie->iCookie.iStartAddress = cbm->iStartBlockAddress +
1.268 + startBlock *
1.269 + cbm->iBlockGranularity +
1.270 + cbm->iBlockStartOffset;
1.271 + iLoaderCookie->iCookie.iFileClamp = aInfo.iFileClamp;
1.272 + // Mark cookie not to be closed yet
1.273 + iLoaderCookie = (TCodeSegLoaderCookieList*) ( ((TInt) iLoaderCookie) | 1);
1.274 + }
1.275 +
1.276 + SRamCodeInfo& ri=RamInfo();
1.277 + ri.iCodeSize=aInfo.iCodeSize;
1.278 + ri.iTextSize=aInfo.iTextSize;
1.279 + ri.iDataSize=aInfo.iDataSize;
1.280 + ri.iBssSize=aInfo.iBssSize;
1.281 + TInt total_data_size=ri.iDataSize+ri.iBssSize;
1.282 + ri.iExportDirCount=aInfo.iExportDirCount;
1.283 + if (total_data_size!=0)
1.284 + {
1.285 + iMark|=(EMarkData|EMarkDataPresent);
1.286 + if (!exeSeg)
1.287 + iMark|=EMarkDataInit;
1.288 + }
1.289 + // if this DLL/EXE doesn't have data, don't set valid bit since we don't yet know about its dependencies
1.290 +
1.291 + if (exeSeg)
1.292 + ri.iDataRunAddr=aProcess->iDataBssRunAddress;
1.293 + r=DoCreateRam(aInfo, aProcess);
1.294 + if (r==KErrNone)
1.295 + {
1.296 + aInfo.iFileEntryPoint+=ri.iCodeRunAddr;
1.297 + aInfo.iExportDir+=ri.iCodeRunAddr;
1.298 + ri.iExportDir=aInfo.iExportDir;
1.299 + aInfo.iCodeLoadAddress=ri.iCodeLoadAddr;
1.300 + aInfo.iCodeRunAddress=ri.iCodeRunAddr;
1.301 + aInfo.iDataLoadAddress=ri.iDataLoadAddr;
1.302 + aInfo.iDataRunAddress=ri.iDataRunAddr;
1.303 + TUint32 xd = aInfo.iExceptionDescriptor;
1.304 + ri.iExceptionDescriptor = xd ? (xd + ri.iCodeRunAddr) : 0;
1.305 + aInfo.iExceptionDescriptor = ri.iExceptionDescriptor;
1.306 + iRunAddress = ri.iCodeRunAddr;
1.307 + }
1.308 + __KTRACE_OPT(KDLL,Kern::Printf("RAM Code Seg: mark %08x attr=%02x xd=%08x",iMark,iAttr,ri.iExceptionDescriptor));
1.309 + __KTRACE_OPT(KDLL,Kern::Printf("<DEpocCodeSeg::DoCreate %d",r));
1.310 + return r;
1.311 + }
1.312 +
1.313 +void DEpocCodeSeg::InitData()
1.314 + {
1.315 + __KTRACE_OPT(KDLL,Kern::Printf("DEpocCodeSeg::InitData %C", this));
1.316 + CHECK_PAGING_SAFE;
1.317 + TInt bss_size=0;
1.318 + TInt data_size=0;
1.319 + TUint8* data_run_ptr=0;
1.320 + const TUint8* data_load_ptr=0;
1.321 + if (iXIP)
1.322 + {
1.323 + const TRomImageHeader& rih=RomInfo();
1.324 + bss_size=rih.iBssSize;
1.325 + data_size=rih.iDataSize;
1.326 + data_run_ptr=(TUint8*)rih.iDataBssLinearBase;
1.327 + data_load_ptr=(const TUint8*)rih.iDataAddress;
1.328 + }
1.329 + else
1.330 + {
1.331 + SRamCodeInfo& ri=RamInfo();
1.332 + bss_size=ri.iBssSize;
1.333 + data_size=ri.iDataSize;
1.334 + data_run_ptr=(TUint8*)ri.iDataRunAddr;
1.335 + data_load_ptr=(const TUint8*)ri.iDataLoadAddr;
1.336 + }
1.337 + UNLOCK_USER_MEMORY();
1.338 + if (data_size)
1.339 + memcpy(data_run_ptr, data_load_ptr, data_size);
1.340 + if (bss_size)
1.341 + memclr(data_run_ptr+data_size, bss_size);
1.342 + LOCK_USER_MEMORY();
1.343 + }
1.344 +
1.345 +DCodeSeg* DCodeSeg::FindRomCode(const TAny* aRomImgHdr)
1.346 + {
1.347 + CHECK_PAGING_SAFE;
1.348 + const TRomImageHeader& rih = *(const TRomImageHeader*)aRomImgHdr;
1.349 + TLinAddr ca = rih.iCodeAddress;
1.350 + return CodeSegsByAddress.Find(ca);
1.351 + }
1.352 +
1.353 +void P::NormalizeExecutableFileName(TDes& /*aFileName*/)
1.354 + {
1.355 + }
1.356 +
1.357 +TInt DEpocCodeSeg::Loaded(TCodeSegCreateInfo& aInfo)
1.358 + {
1.359 + iLoaderCookie = (TCodeSegLoaderCookieList*) ( ((TInt) iLoaderCookie) & ~1);
1.360 + return DCodeSeg::Loaded(aInfo);
1.361 + }
1.362 +
1.363 +
1.364 +//
1.365 +// DEpocCodeSegMemory
1.366 +//
1.367 +
1.368 +DEpocCodeSegMemory::DEpocCodeSegMemory(DEpocCodeSeg* aCodeSeg)
1.369 + : iAccessCount(1), iCodeSeg(aCodeSeg)
1.370 + {
1.371 + }
1.372 +
1.373 +
1.374 +TInt DEpocCodeSegMemory::Open()
1.375 + {
1.376 + return __e32_atomic_tas_ord32(&iAccessCount, 1, 1, 0) ? KErrNone : KErrGeneral;
1.377 + }
1.378 +
1.379 +
1.380 +TInt DEpocCodeSegMemory::Close()
1.381 + {
1.382 + if (__e32_atomic_tas_ord32(&iAccessCount, 1, -1, 0) == 1)
1.383 + {
1.384 + AsyncDelete();
1.385 + return DObject::EObjectDeleted;
1.386 + }
1.387 + return 0;
1.388 + }
1.389 +
1.390 +