First public contribution.
1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32\memmodel\epoc\pcodeseg.cpp
18 #include "plat_priv.h"
21 TLinAddr DCodeSeg::ExceptionDescriptor()
23 DEpocCodeSeg* s = (DEpocCodeSeg*)this;
25 return s->RomInfo().iExceptionDescriptor;
26 return s->RamInfo().iExceptionDescriptor;
29 DEpocCodeSeg::~DEpocCodeSeg()
33 iMemory->iCodeSeg = 0;
39 void DEpocCodeSeg::Destruct()
43 if (iLoaderCookie!=NULL)
45 if ((TInt) iLoaderCookie&1) // Not set fully loaded
47 iLoaderCookie = (TCodeSegLoaderCookieList*) ( ((TInt) iLoaderCookie) & ~1);
53 // Notify reaper of destruction
55 if (DestructNotifyRequest->IsReady())
57 DThread* t = DestructNotifyThread;
58 DestructNotifyThread = NULL;
59 Kern::QueueRequestComplete(t, DestructNotifyRequest,KErrNone);
61 NKern::UnlockSystem();
63 iLoaderCookie->iNext=DestructNotifyList;
64 DestructNotifyList=iLoaderCookie;
73 void DEpocCodeSeg::Info(TCodeSegCreateInfo& aInfo)
78 const TRomImageHeader& rih=RomInfo();
79 aInfo.iCodeSize=rih.iCodeSize;
80 aInfo.iTextSize=rih.iTextSize;
81 aInfo.iDataSize=rih.iDataSize;
82 aInfo.iBssSize=rih.iBssSize;
83 aInfo.iTotalDataSize=rih.iTotalDataSize;
84 aInfo.iExportDir=rih.iExportDir;
85 aInfo.iExportDirCount=rih.iExportDirCount;
86 aInfo.iCodeLoadAddress=rih.iCodeAddress;
87 aInfo.iCodeRunAddress=rih.iCodeAddress;
88 aInfo.iDataLoadAddress=rih.iDataAddress;
89 aInfo.iDataRunAddress=rih.iDataBssLinearBase;
90 aInfo.iExceptionDescriptor = rih.iExceptionDescriptor;
94 const SRamCodeInfo& ri=RamInfo();
95 aInfo.iCodeSize=ri.iCodeSize;
96 aInfo.iTextSize=ri.iTextSize;
97 aInfo.iDataSize=ri.iDataSize;
98 aInfo.iBssSize=ri.iBssSize;
99 aInfo.iTotalDataSize=ri.iDataSize+ri.iBssSize;
100 aInfo.iExportDir=ri.iExportDir;
101 aInfo.iExportDirCount=ri.iExportDirCount;
102 aInfo.iCodeLoadAddress=ri.iCodeLoadAddr;
103 aInfo.iCodeRunAddress=ri.iCodeRunAddr;
104 aInfo.iDataLoadAddress=ri.iDataLoadAddr;
105 aInfo.iDataRunAddress=ri.iDataRunAddr;
106 aInfo.iExceptionDescriptor = ri.iExceptionDescriptor;
108 DCodeSeg::Info(aInfo);
111 void DEpocCodeSeg::GetDataSizeAndBase(TInt& aTotalDataSizeOut, TLinAddr& aDataBaseOut)
115 aTotalDataSizeOut=RomInfo().iTotalDataSize;
116 aDataBaseOut=RomInfo().iDataBssLinearBase;
120 aTotalDataSizeOut=RamInfo().iDataSize+RamInfo().iBssSize;
121 aDataBaseOut=RamInfo().iDataRunAddr;
125 TLibraryFunction DEpocCodeSeg::Lookup(TInt aOrdinal)
128 // return NULL for -ve ordinal or 0th ordinal when not stddll/stdexe
129 if (aOrdinal<0 || (aOrdinal==0 && !(iAttr&ECodeSegAttNmdExpData)))
132 TLinAddr* xd; // points to the 0th ordinal of export table
135 const TRomImageHeader& rih=RomInfo();
136 xdc=rih.iExportDirCount;
137 xd=(TLinAddr*)rih.iExportDir - 1;
141 SRamCodeInfo& ri=RamInfo();
142 xdc=ri.iExportDirCount;
143 xd=(TLinAddr*)ri.iExportDir - 1;
147 UNLOCK_USER_MEMORY();
148 TLibraryFunction f=(TLibraryFunction)xd[aOrdinal];
150 if ((TLinAddr)f == iFileEntryPoint)
152 __KTRACE_OPT(KDLL,Kern::Printf("Lookup(%d)->%08x",aOrdinal,f));
155 __KTRACE_OPT(KDLL,Kern::Printf("Lookup(%d)->NULL",aOrdinal));
159 TInt DEpocCodeSeg::GetMemoryInfo(TModuleMemoryInfo& aInfo, DProcess*)
164 const TRomImageHeader& rih = RomInfo();
165 aInfo.iCodeBase = rih.iCodeAddress;
166 aInfo.iCodeSize = rih.iTextSize;
167 aInfo.iConstDataSize = rih.iCodeSize - aInfo.iCodeSize;
168 aInfo.iConstDataBase = (aInfo.iConstDataSize > 0) ? (aInfo.iCodeBase + aInfo.iCodeSize) : 0;
169 aInfo.iInitialisedDataBase = rih.iDataBssLinearBase;
170 aInfo.iInitialisedDataSize = rih.iDataSize;
171 aInfo.iUninitialisedDataSize = rih.iBssSize;
172 aInfo.iUninitialisedDataBase = aInfo.iInitialisedDataBase+aInfo.iInitialisedDataSize;
176 const SRamCodeInfo& ri = RamInfo();
177 aInfo.iCodeBase = ri.iCodeRunAddr;
178 aInfo.iCodeSize = ri.iTextSize;
179 aInfo.iConstDataSize = ri.iCodeSize - aInfo.iCodeSize;
180 aInfo.iConstDataBase = (aInfo.iConstDataSize > 0) ? (aInfo.iCodeBase + aInfo.iCodeSize) : 0;
181 aInfo.iInitialisedDataBase = ri.iDataRunAddr;
182 aInfo.iInitialisedDataSize = ri.iDataSize;
183 aInfo.iUninitialisedDataSize = ri.iBssSize;
184 aInfo.iUninitialisedDataBase = aInfo.iInitialisedDataBase + aInfo.iInitialisedDataSize;
189 //const TUint32 KRomImageFlagsAlwaysLoaded=KRomImageFlagPrimary|KRomImageFlagVariant|KRomImageFlagExtension;
190 const TUint32 KRomImageDataFlags=(KRomImageFlagData|KRomImageFlagDataInit|KRomImageFlagDataPresent);
191 TInt DEpocCodeSeg::DoCreate(TCodeSegCreateInfo& aInfo, DProcess* aProcess)
193 __KTRACE_OPT(KDLL,Kern::Printf(">DEpocCodeSeg::DoCreate code_addr=%08x",aInfo.iCodeLoadAddress));
196 TBool exeSeg=(iExeCodeSeg==this);
197 TBool kp=exeSeg && (aProcess->iAttributes&DProcess::ESupervisor);
198 TBool user_proc=exeSeg && !kp;
199 if (aInfo.iCodeLoadAddress)
202 iInfo=(const TAny*)aInfo.iCodeLoadAddress;
206 r=aProcess->CreateDataBssStackArea((TProcessCreateInfo&)aInfo);
212 const TRomImageHeader& rih=RomInfo();
214 if ( (rih.iFlags & (KRomImageFlagExeInTree|KRomImageFlagDll)) == (KRomImageFlagExeInTree|KRomImageFlagDll))
216 const TRomImageHeader* exeRIH=rih.iDllRefTable->iEntry[0]; // EXE is always first entry
219 DEpocCodeSeg* pS=(DEpocCodeSeg*)aProcess->CodeSeg();
220 if (!pS->iXIP || &pS->RomInfo()!=exeRIH)
221 return KErrNotSupported;
226 iMark |= (rih.iFlags & KRomImageDataFlags);
227 iMark |= EMarkRecursiveFlagsValid;
228 __KTRACE_OPT(KDLL,Kern::Printf("ROM Code Seg: mark %08x attr=%02x",iMark,iAttr));
229 aInfo.iFileEntryPoint=rih.iEntryPoint;
230 aInfo.iExportDir=rih.iExportDir;
231 aInfo.iCodeLoadAddress=rih.iCodeAddress;
232 aInfo.iCodeRunAddress=rih.iCodeAddress;
233 iRunAddress = rih.iCodeAddress;
234 iSize = rih.iCodeSize;
235 aInfo.iDataLoadAddress=rih.iDataAddress;
236 if (aInfo.iTotalDataSize && user_proc && aProcess->iDataBssRunAddress!=rih.iDataBssLinearBase)
237 K::Fault(K::EProcessDataAddressInvalid);
238 aInfo.iDataRunAddress=rih.iDataBssLinearBase;
239 aInfo.iExceptionDescriptor = rih.iExceptionDescriptor;
240 r=DoCreateXIP(aProcess);
243 iMemory = DEpocCodeSegMemory::New(this);
246 iInfo = &iMemory->iRamInfo;
248 if (aInfo.iUseCodePaging)
250 if ((aInfo.iCodeBlockMapEntries==NULL) || (aInfo.iCodeBlockMapCommon.iLocalDriveNumber<0) ||
251 (((TInt64) (aInfo.iFileClamp.iCookie[0] | aInfo.iFileClamp.iCookie[1]))==0))
254 iLoaderCookie = new TCodeSegLoaderCookieList();
258 SBlockMapInfoBase* cbm = &aInfo.iCodeBlockMapCommon;
261 kumemget32(&startBlock, &aInfo.iCodeBlockMapEntries->iStartBlock, sizeof(TUint));
263 iLoaderCookie->iCookie.iDriveNumber = cbm->iLocalDriveNumber;
264 iLoaderCookie->iCookie.iStartAddress = cbm->iStartBlockAddress +
266 cbm->iBlockGranularity +
267 cbm->iBlockStartOffset;
268 iLoaderCookie->iCookie.iFileClamp = aInfo.iFileClamp;
269 // Mark cookie not to be closed yet
270 iLoaderCookie = (TCodeSegLoaderCookieList*) ( ((TInt) iLoaderCookie) | 1);
273 SRamCodeInfo& ri=RamInfo();
274 ri.iCodeSize=aInfo.iCodeSize;
275 ri.iTextSize=aInfo.iTextSize;
276 ri.iDataSize=aInfo.iDataSize;
277 ri.iBssSize=aInfo.iBssSize;
278 TInt total_data_size=ri.iDataSize+ri.iBssSize;
279 ri.iExportDirCount=aInfo.iExportDirCount;
280 if (total_data_size!=0)
282 iMark|=(EMarkData|EMarkDataPresent);
284 iMark|=EMarkDataInit;
286 // if this DLL/EXE doesn't have data, don't set valid bit since we don't yet know about its dependencies
289 ri.iDataRunAddr=aProcess->iDataBssRunAddress;
290 r=DoCreateRam(aInfo, aProcess);
293 aInfo.iFileEntryPoint+=ri.iCodeRunAddr;
294 aInfo.iExportDir+=ri.iCodeRunAddr;
295 ri.iExportDir=aInfo.iExportDir;
296 aInfo.iCodeLoadAddress=ri.iCodeLoadAddr;
297 aInfo.iCodeRunAddress=ri.iCodeRunAddr;
298 aInfo.iDataLoadAddress=ri.iDataLoadAddr;
299 aInfo.iDataRunAddress=ri.iDataRunAddr;
300 TUint32 xd = aInfo.iExceptionDescriptor;
301 ri.iExceptionDescriptor = xd ? (xd + ri.iCodeRunAddr) : 0;
302 aInfo.iExceptionDescriptor = ri.iExceptionDescriptor;
303 iRunAddress = ri.iCodeRunAddr;
305 __KTRACE_OPT(KDLL,Kern::Printf("RAM Code Seg: mark %08x attr=%02x xd=%08x",iMark,iAttr,ri.iExceptionDescriptor));
306 __KTRACE_OPT(KDLL,Kern::Printf("<DEpocCodeSeg::DoCreate %d",r));
310 void DEpocCodeSeg::InitData()
312 __KTRACE_OPT(KDLL,Kern::Printf("DEpocCodeSeg::InitData %C", this));
316 TUint8* data_run_ptr=0;
317 const TUint8* data_load_ptr=0;
320 const TRomImageHeader& rih=RomInfo();
321 bss_size=rih.iBssSize;
322 data_size=rih.iDataSize;
323 data_run_ptr=(TUint8*)rih.iDataBssLinearBase;
324 data_load_ptr=(const TUint8*)rih.iDataAddress;
328 SRamCodeInfo& ri=RamInfo();
329 bss_size=ri.iBssSize;
330 data_size=ri.iDataSize;
331 data_run_ptr=(TUint8*)ri.iDataRunAddr;
332 data_load_ptr=(const TUint8*)ri.iDataLoadAddr;
334 UNLOCK_USER_MEMORY();
336 memcpy(data_run_ptr, data_load_ptr, data_size);
338 memclr(data_run_ptr+data_size, bss_size);
342 DCodeSeg* DCodeSeg::FindRomCode(const TAny* aRomImgHdr)
345 const TRomImageHeader& rih = *(const TRomImageHeader*)aRomImgHdr;
346 TLinAddr ca = rih.iCodeAddress;
347 return CodeSegsByAddress.Find(ca);
350 void P::NormalizeExecutableFileName(TDes& /*aFileName*/)
354 TInt DEpocCodeSeg::Loaded(TCodeSegCreateInfo& aInfo)
356 iLoaderCookie = (TCodeSegLoaderCookieList*) ( ((TInt) iLoaderCookie) & ~1);
357 return DCodeSeg::Loaded(aInfo);
362 // DEpocCodeSegMemory
365 DEpocCodeSegMemory::DEpocCodeSegMemory(DEpocCodeSeg* aCodeSeg)
366 : iAccessCount(1), iCodeSeg(aCodeSeg)
371 TInt DEpocCodeSegMemory::Open()
373 return __e32_atomic_tas_ord32(&iAccessCount, 1, 1, 0) ? KErrNone : KErrGeneral;
377 TInt DEpocCodeSegMemory::Close()
379 if (__e32_atomic_tas_ord32(&iAccessCount, 1, -1, 0) == 1)
382 return DObject::EObjectDeleted;